内存布局意味着 []T 不能转换为 Go 中的 []interface?

What about memory layout means that []T cannot be converted to []interface in Go?

所以我一直在阅读这两篇文章和这个答案

Cannot convert []string to []interface {} 表示需要更改内存布局。

http://jordanorelli.com/post/32665860244/how-to-use-interfaces-in-go 表示了解底层内存可以让回答这个问题变得容易,并且

http://research.swtch.com/interfaces,解释了幕后发生的事情。

但就我的生活而言,就接口的实现而言,我想不出为什么 []T 不能转换为 []interface 的原因。

为什么?

文章“InterfaceSlice”尽量详细:

A variable with type []interface{} is not an interface! It is a slice whose element type happens to be interface{}. But even given this, one might say that the meaning is clear.

Well, is it? A variable with type []interface{} has a specific memory layout, known at compile time.

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.

另请参阅“what is the meaning of interface{} in golang?

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.

"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!

阅读博客文章 The Laws of Reflection, section The representation of an interface

A variable of interface type stores a pair: the concrete value assigned to the variable, and that value's type descriptor. To be more precise, the value is the underlying concrete data item that implements the interface and the type describes the full type of that item.

所以如果你有一个 []T 的值(T 的一个切片),其中 T 不是接口,这样一个切片的元素只存储类型 T,但不存储类型信息,属于slice类型

如果您有一个 []inteface{} 类型的值,这样一个切片的元素包含具体值 这些值的类型描述符。

因此 []interface{} 中的元素比非接口 []T 中的元素需要更多信息(更多内存)。如果这 2 个切片占用的内存不相同,则它们不能只是 "looked at" 不同(视为不同类型)。从另一个生产一个需要额外的工作。