dpn517111 2019-08-02 07:40
浏览 106
已采纳

无法获取地图元素的地址

I want to find out why

x:= odsMap[segRef]
x.GetValue("@OriginDestinationKey")

works, but this does not:

odsMap[segRef].GetValue("@OriginDestinationKey")

?

The last snippet prints the following errors:

cannot call pointer method on odsMap[segRef]go
cannot take the address of odsMap[segRef]

These errors happen during compilation time (not runtime). So, my main question is why I need an intermediate variable x to access the function?

Regarding the type of the variables odsMap is a map[string] XMLElement and segRef is a string.

Thanks.

  • 写回答

2条回答 默认 最新

  • dowjgrm6787 2019-08-02 07:46
    关注

    Map index expressions are not addressable, because the internals of a map may change when a new entry is added to it, so the spec intentionally does not allow taking its address (this gives greater freedom for map implementations).

    This means if you store non-pointers in the map, and you want to call a method of a stored value that has a pointer receiver, that would require to take the address of the non-pointer value (to be used as the receiver), but since map index expressions are not addressable, that results in a compile-time error.

    A workaround is to store pointer values in the map, so there is no need to take the address of an index expression, because it's already a pointer. An example of this can be seen in this answer: Why should constructor of Go return address? If we have this type:

    type My int
    
    func (m *My) Str() string { return strconv.Itoa(int(*m)) }
    

    This gives the compile-time error in question:

    m := map[int]My{0: My(12)}
    m[0].Str() // Error!
    

    But this works:

    m := map[int]*My{}
    my := My(12)
    m[0] = &my // Store a pointer in the map
    
    m[0].Str() // You can call it, no need to take the address of m[0]
               // as it is already a pointer
    

    Another option is to assign it to a local variable whose address can be taken, and call the pointer method on that. Care must be taken though, as if the method has pointer receiver, it might modify pointed object or its components (e.g. fields of a struct), which would not be reflected in the value stored in the map. If you go down this path, you might have to reassign the value to the key in the map to have the updated value.

    All-in-all, if you have a value whose type has methods with pointer receiver, you're better off using it (store, pass) as a pointer and not as a non-pointer value.

    See related questions:

    Pointer methods on non pointer types

    How can I store reference to the result of an operation in Go?

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

报告相同问题?

悬赏问题

  • ¥100 set_link_state
  • ¥15 虚幻5 UE美术毛发渲染
  • ¥15 CVRP 图论 物流运输优化
  • ¥15 Tableau online 嵌入ppt失败
  • ¥100 支付宝网页转账系统不识别账号
  • ¥15 基于单片机的靶位控制系统
  • ¥15 真我手机蓝牙传输进度消息被关闭了,怎么打开?(关键词-消息通知)
  • ¥15 装 pytorch 的时候出了好多问题,遇到这种情况怎么处理?
  • ¥20 IOS游览器某宝手机网页版自动立即购买JavaScript脚本
  • ¥15 手机接入宽带网线,如何释放宽带全部速度