引用 golang wiki ( https://github.com/golang/go/wiki/MethodSets#interfaces ):
“存储在接口(interface)中的具体值是不可寻址的,就像 map 元素不可寻址一样。”
这里解释了映射值不可寻址的问题: Why are map values not addressable?
但是,接口(interface)方面还不清楚。为什么它们不可寻址?这是因为一些硬设计假设吗?
最佳答案
为什么存储在接口(interface)中的非指针值不可寻址?这是一个很好的问题,答案解释了为什么包含非指针值的接口(interface)不能成为具有指针接收器的方法的接收器,从而导致可怕的错误:
<type> does not implement <interface> (<name> method has pointer receiver)
tl;dr
存储在接口(interface)中的非指针值不可寻址以保持类型完整性。例如,指向接口(interface)中 A 类型值的 A 指针将是当不同类型的值 B 随后存储在接口(interface)中时失效。
因为存储在接口(interface)中的非指针值不可寻址,编译器无法将其地址传递给具有指针接收器的方法。
长答案
我在网上看到的答案没有多大意义。例如,this article说:
The reason is that the value in an interface is in a hidden memory location, and so the compiler can’t automatically get a pointer to that memory for you (in Go parlance, this is known as being “not addressable”).
的确,存储在接口(interface)中的值是不可寻址的,但据我所知,这不是因为它存储在“隐藏的内存位置”。
另一个常见的答案是:
When an interface value is created, the value that is wrapped in the interface is copied. It is therefore not possible to take its address, and even if you did, using a pointer to the interface value would have unexpected effects (ie. unable to alter the original copied value).
这是没有意义的,因为指向复制到接口(interface)中的值的指针与指向复制到具体类型中的值的指针没有区别;在这两种情况下,您都无法通过指向副本的指针更改原始复制值。
那么为什么存储在接口(interface)中的值不可寻址?如果它可寻址,答案就在于后续影响。
假设您有一个接口(interface)I,以及两种类型A 和< em>B,满足那个接口(interface):
type I interface{}
type A int
type B string
创建一个 A 并将其存储在 I 中:
func main() {
var a A = 5
var i I = a
fmt.Printf("i is of type %T\n", i)
假设我们可以获取存储在接口(interface)中的值的地址:
var aPtr *A
aPtr = &(i.(A)) // not allowed, but if it were...
现在创建一个 B 并将其存储在 i 中:
var b B = "hello"
i = b
fmt.Printf("i is of type %T, aPtr is of type %T\n", i, aPtr)
}
这是输出:
i is of type main.A
i is of type main.B, aPtr is of type *main.A
将B放入i后,aPtr 指向? aPtr 被声明为指向 A,但是 t/strong> 现在包含 B,aPtr 不再是指向 A。
但是,这是允许的:
var aPtr *A
var a2 A = i.(A)
aPtr = &a2
因为第二行复制了 i.(A) 和 aPtr 中的值不指向 i.(A)。
那么,为什么包含非指针值的接口(interface)不能成为具有指针接收者的方法的接收者呢?因为存储在接口(interface)中的非指针值不可寻址,所以编译器无法将其地址传递给具有指针接收器的方法。
关于go - 为什么存储在接口(interface)中的值在 Golang 中不可寻址,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48790663/