Golang中嵌套range循环的使用方法

Golang中嵌套range循环的使用方法

package main

import "fmt"

func main() {
        desc := []string{"foo", "bar"}
        exp := []string{"baz", "qux"}

        tmp := make(map[string]string)

        for _, j := range desc {
                for _, n := range exp {
                        tmp[j] = n
                }
        }

        fmt.Println(tmp)
}

这给了我以下输出

map[foo:qux bar:qux]

我原本期望的是

map[foo:baz bar:baz]

因为

键值对必须是唯一的,所以外部循环首先获取 foo,然后内部循环首先获取 baz,所以我们应该得到 tmp["foo"]=baz,然后内部循环迭代到 quxtmp["foo"] 已经被设置,所以 tmp["foo"]=qux 被拒绝,外部循环现在迭代到 bar,我们遵循相同的逻辑,最后应该得到我所期望的结果。

有人能解释一下为什么结果是这样的吗?


更多关于Golang中嵌套range循环的使用方法的实战教程也可以访问 https://www.itying.com/category-94-b0.html

2 回复

明白了为什么会出现这样的结果,tmp["foo"]=qux 没有被拒绝,而是被成功赋值,因此我得到了这个结果。

更多关于Golang中嵌套range循环的使用方法的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


你的理解有误。问题不在于键的唯一性,而在于你的嵌套循环逻辑导致了覆盖。

在你的代码中,对于每个外部循环的键,内部循环会遍历整个切片,最终该键的值会被设置为内部循环的最后一个元素。

让我详细解释一下执行过程:

package main

import "fmt"

func main() {
    desc := []string{"foo", "bar"}
    exp := []string{"baz", "qux"}
    
    tmp := make(map[string]string)
    
    for _, j := range desc {        // 外部循环
        for _, n := range exp {     // 内部循环
            fmt.Printf("设置 tmp[%s] = %s\n", j, n)
            tmp[j] = n
        }
        fmt.Println()
    }
    
    fmt.Println("最终结果:", tmp)
}

输出:

设置 tmp[foo] = baz
设置 tmp[foo] = qux

设置 tmp[bar] = baz
设置 tmp[bar] = qux

最终结果: map[bar:qux foo:qux]

执行顺序:

  1. j = "foo" 时:

    • tmp["foo"] = "baz"
    • tmp["foo"] = "qux" ← 覆盖了之前的值
  2. j = "bar" 时:

    • tmp["bar"] = "baz"
    • tmp["bar"] = "qux" ← 覆盖了之前的值

如果你想要 map[foo:baz bar:baz],应该使用单层循环:

package main

import "fmt"

func main() {
    desc := []string{"foo", "bar"}
    exp := []string{"baz", "qux"}
    
    tmp := make(map[string]string)
    
    for i, j := range desc {
        tmp[j] = exp[i]
    }
    
    fmt.Println(tmp) // 输出: map[bar:qux foo:baz]
}

或者如果你想要每个desc元素对应exp的第一个元素:

package main

import "fmt"

func main() {
    desc := []string{"foo", "bar"}
    exp := []string{"baz", "qux"}
    
    tmp := make(map[string]string)
    
    for _, j := range desc {
        tmp[j] = exp[0] // 总是使用exp的第一个元素
    }
    
    fmt.Println(tmp) // 输出: map[bar:baz foo:baz]
}

嵌套循环在这里是不必要的,因为对于每个键,你只需要一个值,而不是遍历所有可能的值。

回到顶部