为什么在Golang中使用count++(而不是count = count + 1)会改变map的返回方式?

huangapple go评论84阅读模式
英文:

Why does count++ (instead of count = count + 1) change the way the map is returned in Golang

问题

我使用了一个以句子中的单词作为键,整数作为值的映射。以下是代码的翻译:

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++则相反呢?

英文:

I used a map that uses words from a sentence as its keys and integers as the values.

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"))
}

The above code ALWAYS displays the map in the correct order, i.e.

map[I:1 am:2 learning:3 GO:4 since:5 some:6 days:7]

But if I change

count = count + 1

to

count++

The Output changes to:

map[learning:3 GO:4 since:5 some:6 days:7 I:1 am:2]

I know that map iteration is random in Golang but why does count = count + 1 always cause the map iteration to be returned in an ordered fashion contrary to count++?

答案1

得分: 16

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

迭代顺序没有"正确"的顺序,可以将其视为随机的(在当前实现中确实是随机的)。引用自语言规范:For语句

映射的迭代顺序未指定,并且不能保证从一次迭代到下一次迭代是相同的。

有关此主题的更多信息,请查看此答案:为什么Go不能按插入顺序迭代映射?

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

但是,如果您更改了代码,那么它将被视为新代码,并且将被编译和运行(其输出将在之后被缓存)。由于它是重新运行的,您可能会观察到新的随机顺序-这就是您的情况。

如果您再次更改代码,即使是添加或更改一些注释,输出也会(可能)再次更改,请尝试一下。

有关Playground的实现方式的更多信息,请参阅博文**Go Playground内部情况**。

引用相关部分:

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

还要注意,从Go 1.12开始,使用fmt包打印映射时,映射会被排序(以便进行测试),因此现在始终以相同的顺序列出元素。迭代顺序仍然是故意的非确定性。

英文:

The way how you change the value of the count variable has nothing to do with the iteration order of the map elements.

There is no "correct" iteration order, the iteration order can be thought of as random (and in current implementation it is random). Quoting from the language spec: For statements:

> The iteration order over maps is not specified and is not guaranteed to be the same from one iteration to the next.

For more on the topic, check out this answer: Why can't Go iterate maps in insertion order?

The Go Tour uses the Go Playground to provide a code editor and runner. The Go Playground caches the output of the codes you run on it. Running twice the exact same code will just show you the cached output.

If you change your code however, that is "treated" as new code and it will be compiled and ran (and its output will be cached after). And since it is run anew, you may observe a new random order - which you do.

If you change again something in the code, even as insignificant as adding or changing some comment, the output will (may) change again, try it.

For more information on how the Playground is implemented, see blog post Inside the Go Playground.

Quoting the relevant part:

> When the front end receives a compilation request it first checks memcache to see if it has cached the results of a previous compilation of that source. If found, it returns the cached response. The cache prevents popular programs such as those on the Go home page from overloading the back ends. If there is no cached response, the front end makes an RPC request to the back end, stores the response in memcache, parses the playback events, and returns a JSON object to the client as the HTTP response (as described above).

Also note that starting with Go 1.12, maps are sorted when printed using the fmt package (to ease testing), so printing the same map now will always list elements in the same order. The iteration order still remains non-deterministic deliberately.

huangapple
  • 本文由 发表于 2015年10月6日 17:34:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/32966514.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定