douren5490 2018-02-14 15:25
浏览 148
已采纳

为什么接口中存储的值无法在Golang中寻址

Citing the golang wiki (https://github.com/golang/go/wiki/MethodSets#interfaces):

"The concrete value stored in an interface is not addressable, in the same way, that a map element is not addressable."

The question of map values not being addressable is explained here: Why are map values not addressable?

However, it is not clear regarding the interface. Why are they not addressable? Is this because of some hard design assumption?

  • 写回答

3条回答 默认 最新

  • dqdz6464 2018-02-19 21:44
    关注

    Why isn't a non-pointer value stored in an interface addressable? This is an excellent question, and the answer explains why an interface containing a non-pointer value can't be the receiver for a method with a pointer receiver, leading to the dreaded error:

    <type> does not implement <interface> (<name> method has pointer receiver)
    

    tl;dr

    A non-pointer value stored in an interface isn't addressable to maintain type integrity. For example, a pointer to A, which points to a value of type A in an interface, would be invalidated when a value of a different type B is subsequently stored in the interface.

    Because a non-pointer value stored in an interface isn't addressable, the compiler can't pass its address to a method with a pointer receiver.

    Long answer

    The answers I've seen online don't make much sense. For instance, this article says:

    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”).

    It's true that the value stored in an interface is not addressable, but as far as I can see it's not because its stored in "a hidden memory location".

    Another common answer is:

    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).

    This makes no sense, since a pointer to a value copied into an interface would be no different than a pointer to a value copied into a concrete type; in both cases you can't alter the original copied value through the pointer to the copy.

    So why isn't a value stored in an interface addressable? The answer lies in the follow-on implications if it were addressable.

    Let's say you have an interface, I, and two types, A and B, which satisfy that interface:

    type I interface{}
    type A int
    type B string
    

    Create an A and store it in an I:

    func main() {
        var a A = 5
        var i I = a
        fmt.Printf("i is of type %T
    ", i)
    

    Let's pretend we could take the address of a value stored in an interface:

        var aPtr *A
        aPtr = &(i.(A)) // not allowed, but if it were...
    

    Now create a B and store it in i:

        var b B = "hello"
        i = b
        fmt.Printf("i is of type %T, aPtr is of type %T
    ", i, aPtr)
    }
    

    Here's the output:

    i is of type main.A
    i is of type main.B, aPtr is of type *main.A
    

    After putting a B into i, what is aPtr pointing to? aPtr was declared as pointing to an A, but t now contains a B, and aPtr is no longer a valid pointer to A.

    This, however is permitted:

        var aPtr *A
        var a2 A = i.(A)
        aPtr = &a2
    

    Because the second line makes a copy of the value in i.(A), and aPtr does not point to i.(A).

    So, why can't an interface containing a non-pointer value be the receiver for a method with a pointer receiver? Because a non-pointer value stored in an interface isn't addressable, so the compiler can't pass its address to a method with a pointer receiver.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

悬赏问题

  • ¥15 用stata实现聚类的代码
  • ¥15 请问paddlehub能支持移动端开发吗?在Android studio上该如何部署?
  • ¥170 如图所示配置eNSP
  • ¥20 docker里部署springboot项目,访问不到扬声器
  • ¥15 netty整合springboot之后自动重连失效
  • ¥15 悬赏!微信开发者工具报错,求帮改
  • ¥20 wireshark抓不到vlan
  • ¥20 关于#stm32#的问题:需要指导自动酸碱滴定仪的原理图程序代码及仿真
  • ¥20 设计一款异域新娘的视频相亲软件需要哪些技术支持
  • ¥15 stata安慰剂检验作图但是真实值不出现在图上