我使用了一个映射,该映射使用句子中的单词作为键,并使用整数作为值。
func WordCount(s string) map[string]int { var m map[string]int m = make(map[string]int) var substrings[]string count := 0 substrings = strings.Split(s, " ") for i := range substrings { count = count + 1 m[substrings[i]] = count } return m } func main() { fmt.Println(WordCount("I am learning GO since some days")) }
上面的代码 始终 以正确的顺序显示地图,即
map[I:1 am:2 learning:3 GO:4 since:5 some:6 days:7]
但是如果我改变
count = count + 1
至
count++
输出更改为:
map[learning:3 GO:4 since:5 some:6 days:7 I:1 am:2]
我知道在Golang中地图迭代是随机的,但是为什么count = count + 1总是导致地图迭代以有序方式返回却又相反count++呢?
更改变量值的方式count与映射元素的迭代顺序无关。
count
没有“正确的”迭代顺序,可以将迭代顺序视为随机的(在当前实现中,它 是 随机的)。从语言规范中引用:对于语句:
未指定地图的迭代顺序,并且不能保证每次迭代之间都相同。
Go Tour使用Go Playground提供代码编辑器和运行器。Go Playground会缓存您在其上运行的代码的输出。运行两次完全相同的代码只会向您显示缓存的输出。
但是,如果您更改代码,则将其“视为”新代码,并将对其进行编译和运行(其输出将在之后进行缓存)。并且由于它是新运行的,因此您可能会观察到一个新的随机顺序- 您正在执行。
如果您再次更改了代码中的某些内容,即使添加或更改了一些注释也没什么大不了,那么输出(可能)将再次更改,请尝试一下。
有关如何实现Playground的更多信息,请参阅博客文章 Inside Go Playground 。
引用相关部分:
当前端收到编译请求时,它首先检查memcache,以查看它是否已缓存该源的先前编译结果。 如果找到,它将返回缓存的响应。 缓存可防止热门程序(例如Go主页上的程序)使后端过载。如果没有缓存的响应,则前端向后端发出RPC请求,将响应存储在内存缓存中,解析回放事件,然后将JSON对象作为HTTP响应返回给客户端(如上所述)。
另请注意,从Go 1.12开始,使用fmt包打印地图时会对其进行排序(以简化测试),因此,现在打印相同的地图将始终以相同的顺序列出元素。迭代顺序仍然有意保持不确定性。
fmt