一尘不染

为什么count ++(而不是count = count + 1)会改变Golang中返回地图的方式

go

我使用了一个映射,该映射使用句子中的单词作为键,并使用整数作为值。

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++呢?


阅读 365

收藏
2020-07-02

共1个答案

一尘不染

更改变量值的方式count与映射元素的迭代顺序无关。

没有“正确的”迭代顺序,可以将迭代顺序视为随机的(在当前实现中,它
随机的)。从语言规范中引用:对于语句

未指定地图的迭代顺序,并且不能保证每次迭代之间都相同。

Go Tour使用Go
Playground
提供代码编辑器和运行器。Go
Playground会缓存您在其上运行的代码的输出。运行两次完全相同的代码只会向您显示缓存的输出。

但是,如果您更改代码,则将其“视为”新代码,并将对其进行编译和运行(其输出将在之后进行缓存)。并且由于它是新运行的,因此您可能会观察到一个新的随机顺序-
您正在执行。

如果您再次更改了代码中的某些内容,即使添加或更改了一些注释也没什么大不了,那么输出(可能)将再次更改,请尝试一下。

有关如何实现Playground的更多信息,请参阅博客文章 Inside Go
Playground

引用相关部分:

当前端收到编译请求时,它首先检查memcache,以查看它是否已缓存该源的先前编译结果。
如果找到,它将返回缓存的响应。
缓存可防止热门程序(例如Go主页上的程序)使后端过载。如果没有缓存的响应,则前端向后端发出RPC请求,将响应存储在内存缓存中,解析回放事件,然后将JSON对象作为HTTP响应返回给客户端(如上所述)。

另请注意,从Go
1.12
开始,使用fmt包打印地图时会对其进行排序(以简化测试),因此,现在打印相同的地图将始终以相同的顺序列出元素。迭代顺序仍然有意保持不确定性。

2020-07-02