所以我一直在阅读这两篇文章和这个答案
Cannot convert []string to []interface {}表示需要更改内存布局。
http://jordanorelli.com/post/32665860244/how-to-use-interfaces-in-go表示理解底层记忆可以轻松回答这个问题,
http://research.swtch.com/interfaces,解释了幕后发生的事情。
但对于我的生活,我无法想到一个原因,就接口的实现而言,为什么[] T不能被强制转换为[]接口。
为什么?
答案 0 :(得分:4)
文章" InterfaceSlice"试着详细说明:
类型为
好吧,是吗?类型为[]interface{}
的变量不是接口!它是一个切片,其元素类型恰好是interface{}
。但即使考虑到这一点,也许可以说意思很明确。[]interface{}
的变量具有特定的内存布局,在编译时已知。每个
interface{}
占用两个单词(一个单词表示包含的内容,另一个单词表示包含的数据或指向它的指针)。因此,长度为N且类型为[]interface{}
的切片由一长N * 2个字的数据块支持。
另见" what is the meaning of interface{}
in golang?"
这与支持类型为
[]MyType
且长度相同的切片的数据块不同。它的数据块长N*sizeof(MyType)
个字。结果是您无法快速将
[]MyType
类型的内容分配给[]interface{}
类型的内容;他们背后的数据看起来不同。
" why []string
can not be converted to []interface{}
in Go"增加了一个很好的例证:
// imagine this is possible
var sliceOfInterface = []interface{}(sliceOfStrings)
// since it's array of interface{} now - we can do anything
// let's put integer into the first position
sliceOfInterface[0] = 1
// sliceOfStrings still points to the same array, and now "one" is replaced by 1
fmt.Println(strings.ToUpper(sliceOfStrings[0])) // BANG!
答案 1 :(得分:1)
阅读博客文章The Laws of Reflection,The representation of an interface部分。
接口类型的变量存储一对:赋给变量的具体值,以及该值的类型描述符。更确切地说,值是实现接口的基础具体数据项,类型描述该项的完整类型。
因此,如果您的值为[]T
(T
的一片),其中T
不是接口,则此类切片的元素仅存储类型{{1但它不存储类型信息,它属于切片类型。
如果您的值为T
,则此类切片的元素将保存具体值和这些值的类型描述符。
因此[]inteface{}
中的元素需要比非接口[]interface{}
更多的信息(更多内存)。如果这两个切片的占用内存不相同,那么它们就不能只是看着#34;不同(看作不同的类型)。从另一个生产一个需要额外的工作。