doufen1933
doufen1933
2017-08-30 18:20

在Go中复制循环变量的地址

In the following code sample, the result is not what I would expect:

package main

import "fmt"

func main() {
    src := map[int]int{1: 1, 2: 2, 3: 3}
    fmt.Println("src ", src)

    dst := make([]*int, 0, len(src))
    for k, _ := range src {
        dst = append(dst, &k)
    }
    for _, a := range dst {
        fmt.Print(*a, " ")
    }
    fmt.Println()
}

Result:

src map[1:1 2:2 3:3]
3 3 3

Go Playground: https://play.golang.org/p/BSDsd3nojz

but I understand what is happening. The unchanging address of k is being added to dst, so when I loop over dst, the same value is in every location: 3.

The address of k never changes in the loop, so the second loop keeps referring to that location, containing the last value it had, 3.

How can I get the address of the current value of k to be copied? Do I need something like this:

for k, _ := range src {
    key = new(int)
    *key = k
    dst = append(dst, key)
}

That seems awkward.

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享
  • 邀请回答

1条回答

  • dongqichang7988 dongqichang7988 4年前

    If you have a map[T]X and you want to get a []*T, you are on the right track with copying the loop variable and getting an address to it.

    There is a slightly slimmer way to do it than your way:

    for k := range src {
        key := k
        dst = append(dst, &key)
    }
    

    What you are adding to dst is not the address of the keys or values in the map, but rather the address of a copy of the key. That distinction may or may not matter to you.

    The reason that using the address of the loop variables doesn't work, is that the loop variables are single locations that get updated on each iteration. Value types like ints and structs are copyed each time you assign it to a new variable.

    点赞 评论 复制链接分享

为你推荐