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

标签 interface go language-design duck-typing memory-layout

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

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

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

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

但就我的生活而言,就接口(interface)的实现而言,我想不出为什么 []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?

2 words

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!

关于interface - 内存布局意味着 []T 不能转换为 Go 中的 []interface?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29026241/

相关文章:

c++ - C++ 中的编译时接口(interface)实现检查

go - 配置 Keycloak 以在 id token 中包含 at_hash 声明

go - 在父类(super class)的子类上找不到接口(interface)方法

python - 为什么 Python 列表加法必须是同质的?

python - 为什么 os.path.join 会丢弃参数?

dynamic - 为什么 Clojure 是动态类型的?

c# - 使用接口(interface) - 设计模式方面

c# - "yield"返回不同的类型?

java - 强制用户在 Java 中声明变量

testing - 如何在 Golang 中测试参数的传递?