【问题标题】:Why does count++ (instead of count = count + 1) change the way the map is returned in Golang为什么count++(而不是count = count + 1)会改变Golang中返回地图的方式
【发布时间】:2015-10-06 09:34:12
【问题描述】:

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

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

上面的代码ALWAYS以正确的顺序显示地图,即

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++ 相反的有序方式返回?

【问题讨论】:

  • 您是否有机会在 Go Playground 上对其进行测试?如果是这样,则缓存 Playground 上的输出!
  • 我不是在谈论代码的来源,而是在谈论你在哪里运行/测试它。
  • 我在 golang tour 上跑过

标签: dictionary go hashmap


【解决方案1】:

改变count变量值的方式与地图元素的迭代顺序无关。

没有“正确”的迭代顺序,迭代顺序可以被认为是随机的(在当前的实现中它随机的)。引用自language spec: For statements

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

有关该主题的更多信息,请查看此答案:Why can't Go iterate maps in insertion order?

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

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

如果您再次更改代码中的某些内容,即使添加或更改某些注释微不足道,输出也会(可能)再次更改,请尝试一下。

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

引用相关部分:

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

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

【讨论】:

  • 是的,似乎是这样。我在本地编译器上运行它,无论我使用 count = count + 1 还是 count ++,它在所有情况下都会给出随机输出。非常感谢!
  • OT 你的代码看起来不像 Go ideomatic。可以简化(例如play.golang.org/p/E4k2BxQWMV
  • 从 1.12 开始,地图在 打印 时使用 fmt 的打印功能进行排序。当以其他方式访问时,它们仍然(故意)未排序——tip.golang.org/doc/go1.12#fmtgithub.com/golang/go/issues/21095
猜你喜欢
  • 2013-02-25
  • 2015-09-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-06
  • 2022-11-02
相关资源
最近更新 更多