据我了解,索引地图会返回地图值的副本。考虑到这一点,请考虑以下代码:package mainimport "fmt"func main() { m := map[string]int{"xxx": 100} m["xxx"]++ fmt.Println(m["xxx"]) // prints 101}上面的代码打印101,而我的预期100。我的推理是m["xxx"]返回分配给键的值的副本"xxx"(即,100),并且操作员++递增该值的副本,但这不会影响存储在映射中的原始值——只有副本发生了变化。但是,考虑到我们通过将键放在括号内并使用=来指定值(即m[key] = value)来为映射键分配值。然后,如果m["xxx"]++被m["xxx"] += 1编译器翻译成 - 这反过来,相当于m["xxx"] = m["xxx"] + 1- 这将解释上面代码的结果。我的问题是增量运算符 ( ++) 是否是加法赋值 ( ) 的语法糖+= 1。否则,我错过了什么?
2 回答
婷婷同学_
TA贡献1844条经验 获得超8个赞
“我的理由是 m["xxx"] 返回值的副本” ——我认为这不是一个公平的假设。索引表达式下的规范仅说明以下内容:
表单的主要表达式表示[...] 映射的
a[x]
元素a
x
和
如果地图包含一个带有 key 的条目
x
,a[x]
是带有 key 的地图元素x
动词“表示”和“是”可以说并不意味着副本。仅当您将索引表达式的结果分配给变量时才会进行复制。
地图索引表达式根本不可寻址,因此您无法记忆地图中存储的值的别名。
至于增量运算符是否++
是语法糖+= 1
,规范明确指出:
以下赋值语句在语义上是等价的:
IncDec 语句分配 x++ x += 1 x-- x -= 1
Soop++
与 具有相同的含义op += 1
,并且使用 keya[x]++
递增a[x]
“表示/是”映射元素的操作数x
。
梵蒂冈之花
TA贡献1900条经验 获得超5个赞
语言规范说 ++/-- 运算符应该使用映射索引表达式作为操作数。
https://go.dev/ref/spec#IncDec_statements
“++”和“--”语句通过无类型常量 1 递增或递减它们的操作数。与赋值一样,操作数必须是可寻址的或映射索引表达式。
未指定应如何实现该功能,因此在不同编译器或同一编译器的不同版本之间可能会有所不同。
如果你搜索cmd/compile/internal
你的 Go 安装目录,如果我没记错的话,这是 Go 编译器的源代码,你会发现很多行似乎证实了你的猜测。但是,我对代码的了解还远远不够,无法提供结论性的答案。
我从未看过的规范的gccgo
实现可能会也可能不会以同样的方式执行 IncDec。
- 2 回答
- 0 关注
- 152 浏览
添加回答
举报
0/150
提交
取消