type eface struct { _type *_type data unsafe.Pointer }
所以即使两个变量都是interface{}类型,但底层的类型不同,则两个变量不相等
1 2 3 4 5
var ( a interface{} = 123 b interface{} = "string" ) fmt.Println(a == b) // false
那么对于[]interface{}类型的变量来说,切片里的每个元素可以存储不同类型的变量,例如
1 2 3 4 5 6
funcmain() { var a = make([]interface{}, 0) a = append(a, []int{123, 456}) a = append(a, []string{"abc", "ijk"}) fmt.Println(a) // [[123 456] [abc ijk]] }
但即使切片里存的数据都是某个特定的类型,也不能通过类型断定来强制转换,因为底层的数据存储结构不同
1 2 3 4 5 6 7 8 9 10 11 12
funcmain() { a := method() _, ok := a.([]int) fmt.Println(ok) // false }
funcmethod()interface{} { var a = make([]interface{}, 0) a = append(a, []int{123, 456}) a = append(a, []int{789, 111}) return a }
Each interface{} takes up two words (one word for the type of what is contained, the other word for either the contained data or a pointer to it). As a consequence, a slice with length N and with type []interface{} is backed by a chunk of data that is N*2 words long.
This is different than the chunk of data backing a slice with type []MyType and the same length. Its chunk of data will be N*sizeof(MyType) words long.
The result is that you cannot quickly assign something of type []MyType to something of type []interface{}; the data behind them just look different.
那么如果我们要把同类型组成的切片转换成的特定类型,可以这样做
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
funcmain() { a := method() ans := make([][]int, 0) b, ok := a.([]interface{}) if ok { for _, element := range b { ans = append(ans, element.([]int)) } } fmt.Println(ans) // [[123 456] [789 111]] }
funcmethod()interface{} { var a = make([]interface{}, 0) a = append(a, []int{123, 456}) a = append(a, []int{789, 111}) return a }