2016-09-07 66 views
2

我有一個功能。如何在Go中創建一個變量類型片?

func doSome(v interface{}) { 

} 

如果我通過指針向函數傳遞一個結構片,函數必須填充切片。

type Color struct { 
} 
type Brush struct { 
} 

var c []Color 
doSome(&c) // after с is array contains 3 elements type Color 

var b []Brush 
doSome(&b) // after b is array contains 3 elements type Brush 

也許我需要使用反射,但如何?

回答

1
func doSome(v interface{}) { 

    s := reflect.TypeOf(v).Elem() 
    slice := reflect.MakeSlice(s, 3, 3) 
    reflect.ValueOf(v).Elem().Set(slice) 

} 
1

typeswitch !!

package main 
import "fmt" 

func doSome(v interface{}) { 
    switch v := v.(type) { 
    case *[]Color: 
    *v = []Color{Color{0}, Color{128}, Color{255}} 
    case *[]Brush: 
    *v = []Brush{Brush{true}, Brush{true}, Brush{false}} 
    default: 
    panic("unsupported doSome input") 
    } 
} 

type Color struct { 
    r uint8 
} 
type Brush struct { 
    round bool 
} 

func main(){ 
    var c []Color 
    doSome(&c) // after с is array contains 3 elements type Color 

    var b []Brush 
    doSome(&b) // after b is array contains 3 elements type Brush 

    fmt.Println(b) 
    fmt.Println(c) 

} 
+0

沒有! :)它的不好的做法。如果我添加新類型,函數doSome()需要修改。 –

+0

我認爲這是很好的做法,因爲它迫使你明確地編寫'doSome()'而不是猜測行爲。如果你想doSome總是創建EMPTY切片,那麼你可以使用'b:= make([] Brush,3)'而不是'doSome(&b)' – Plato

0

Go沒有仿製藥。您的可能性是:

接口調度

type CanTraverse interface { 
    Get(int) interface{} 
    Len() int 
} 
type Colours []Colour 

func (c Colours) Get(i int) interface{} { 
    return c[i] 
} 
func (c Colours) Len() int { 
    return len(c) 
} 
func doSome(v CanTraverse) { 
    for i := 0; i < v.Len; i++ { 
     fmt.Println(v.Get(i)) 
    } 
} 

型交換機作爲@Plato建議

func doSome(v interface{}) { 
    switch v := v.(type) { 
    case *[]Colour: 
    //Do something with colours 
    case *[]Brush: 
    //Do something with brushes 
    default: 
    panic("unsupported doSome input") 
    } 
} 

反思fmt.Println()做的。反射非常強大,但非常昂貴,代碼可能很慢。小例子

func doSome(v interface{}) { 
    value := reflect.ValueOf(v) 
    if value.Kind() == reflect.Slice { 
     for i := 0; i < value.Len(); i++ { 
      element := value.Slice(i, i+1) 
      fmt.Println(element) 
     } 
    } else { 
     fmt.Println("It's not a slice") 
    } 
} 
相關問題