Golang 的 []interface{} 類型
我其實不太喜歡使用 Go 語言的 interface{} 類型,一般情況下我寧願多寫幾個函數:XxxInt, XxxFloat, XxxString……
但是今天發現一個有意思的事情。
假如我們有這樣一個函數:
func Foo(a interface{}) {}
Foo(1)
Foo("str")
Foo(1.552)
那么我們可以傳入任何類型作為參數,因為任何類型都實現了 interface{} 接口,所以自然可以傳入任意類型。
當我們聲明 interface{} 數組的時候,事情就變的不一樣了:
func Foo(a []interface{}) {}
Foo([]int{1, 2, 3}) // 報錯
Foo([]string{"1", "2", "3"}) // 報錯
按照本身的設想,這里應該不管什么樣的數組都可以作為參數傳入,可是結果卻恰恰相反:我們只能傳入類型為 []interface{} 的元素。
為什么呢?
因為 []interface{} 類型變量擁有特定的內存結構。
每個 interface{} 占兩個字(32 位機器一個字是 32 位,64 位機器一個字是 64 位)。其中,一個字用於存放 interface{} 真正傳入的數據的類型;另一個字用於指向實際的數據。
因此我們可以得出:長度為 n 的 []interface{} 切片的背后,是一個 n * 2 字 長的一塊數據。這與一般的 []Type 類型切片不同的。
而長度為 n 的 []Type 切片的背后數據分配的大小為為 n * sizeof(Type) 字 長。
自然就不可以將 []int 類型作為 []interface{} 類型進行傳遞,只能自己寫個循環將每一個 Type 都轉化為 interface{}。
(完)
