dictionary - 无法获取 map 元素的地址

标签 dictionary pointers go methods

我想知道为什么

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

有效,但这不是:

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

?

最后一段打印出以下错误:

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

这些错误发生在编译时(而非运行时)。所以,我的主要问题是为什么我需要一个中间变量 x 来访问函数?

关于变量的类型 odsMap 是一个 map[string] XMLElement 而 segRef 是一个字符串。

谢谢。

最佳答案

Map 索引表达式是不可寻址的,因为当向其中添加新条目时,Map 的内部结构可能会发生变化,因此规范有意不允许获取其地址(这为 Map 实现提供了更大的自由度)。

这意味着如果您在映射中存储非指针,并且您想要调用具有指针接收器的存储值的方法,这将需要获取非指针值的地址(用作接收器),但由于映射索引表达式不可寻址,因此会导致编译时错误。

解决方法是将指针值存储在映射中,因此无需获取索引表达式的地址,因为它已经是一个指针。可以在这个答案中看到一个例子:Why should constructor of Go return address?如果我们有这种类型:

type My int

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

这给出了有问题的编译时错误:

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

但这行得通:

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

另一种选择是将其分配给一个可以获取其地址的局部变量,并在其上调用指针方法。但必须小心,因为如果该方法具有指针接收器,它可能会修改指向的对象或其组件(例如结构的字段),这不会反射(reflect)在映射中存储的值中。如果沿着这条路走下去,您可能必须将值重新分配给映射中的键才能获得更新后的值。

总而言之,如果您的值的类型具有带指针接收器的方法,则最好将其用作(存储、传递)指针而不是非指针值。

查看相关问题:

Pointer methods on non pointer types

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

关于dictionary - 无法获取 map 元素的地址,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57321933/

相关文章:

ios - 无法在深度嵌套的数据结构上下标错误

c++ - 迭代 char** 为什么这行得通?

C# 在特定内存地址创建对象

api - 如何在Golang中从服务器发送Websocket

go - 不需要的 Glide 导入

go - golang defer语句是在return语句之前还是之后执行?

c++ - 从两个不同的数据结构将数据插入 std::map <std::string, int> mymap 并通过套接字发送

json - 使用 Swift 可解码解析 JSON 字典时出错

ios - 如何使用字典中分组结构中的数据填充 UITableView?

c - 斯坦福大学的指针和内存