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{}
。
(完)