2017-09-06 22 views
-1

我有一個函數,我想要餵食不同種類的切片,之後我想循環它們並打印它們的內容。下面的代碼工作:轉:如何獲得切片的長度功能?

func plot(data interface{}){ 
    fmt.Println(data) 
    //fmt.Println(len(data)) 
} 

func main() { 
    l := []int{1, 4, 3} 
    plot(l) 
} 

但是,當我取消我在其中打印片長度的線,我得到一個錯誤說invalid argument data (type interface {}) for len

任何想法我將如何能夠獲得切片的長度,以便我可以循環它?

+0

@每個問題CeriseLimón不同的數據類型不同的功能的利弊「我要送不同種類的切片」。 – Adrian

+0

如果參數是一個空的接口,你必須使用'reflect'包來做你想做的事。請參閱https://golang.org/pkg/reflect。你可能要考慮如何定義,定義了執行任何操作,你需要在你進入。此外, –

+0

如果你使用不同種類的切片工作對象執行方法的一個特定的接口,你必須已經使用反射或斷言他們具體類型。你如何使用'data'已經無法獲得長度? – JimB

回答

3

儘可能避免使用interface {}。你想做的事情可以用反思來完成,但反思是必要的罪惡。編組真的很好,但應該謹慎使用。如果你仍然想使用反射,你可以做這樣的事情:

func plot(data interface{}) { 
    s := reflect.ValueOf(data) 
    if s.Kind() != reflect.Slice { 
     panic("plot() given a non-slice type") 
    } 

    for i := 0; i < s.Len(); i++ { 
     v := s.Index(i) 
     ... 
    } 
} 

即使這樣做後,v是reflect.Value。然後您需要以某種方式將其轉換爲有用的東西。幸運的是,Value有很多方法可以用來轉換它。在這種情況下,v.Int()會將該值作爲int64返回。

1

正如評論暗示你將不得不使用反射來做到這一點,類似如下:

var sliceLen int 

switch reflect.TypeOf(data).Kind() { 

    case reflect.Slice: 
     sliceLen = s.Len(); 
    default: 
     //error here, unexpected 
    } 
} 

雖然旅途提供了反思的時候,你需要(以及許多其他用途做這些小動作),它往往是更好地避免儘可能保持編譯類型的安全性和性能,可以考慮利弊/有過這種做法