2016-04-28 12 views
2

スライス(src)のすべてのアイテムを新しいスライス(dst)にコピーした後、dstのすべてのアイテムをsrcの最後のアイテムを指します。ゴランレンジコピー後、すべてのアイテムがsrcスライスの最後のアイテムを指します

package main 

import (
    "fmt" 
) 

func main() { 
    src := []string{"a", "b", "c"} 
    dst := []*string{} 
    for _, val := range src { 
     dst = append(dst, &val) 
    } 

    for i, s := range dst { 
     fmt.Printf("%v - %v\n", i, *s) 
    } 
} 

>>> 0 - c 
>>> 1 - c 
>>> 2 - c 

dstスライスに "a"と "b"がコピーされないのはなぜですか?

+0

私は重複としてマークしませんが、以下を参照してください。https://golang.org/ doc/faq#closures_and_goroutines – JimB

答えて

6

解決方法は簡単ですが、rangeの文章で予想される内容は直感的です。

変数valは一度だけインスタンス化され、すべての反復でsrc[i]を保持しています。 src[i]への実際のポインタはありません。代わりに、に割り当てられたメモリにsrc[i]の値がコピーされます。 valのポインタを取ることによって、正確にそれを取得し、src[i]へのポインタではありません。

package main 

import (
    "fmt" 
) 

func main() { 
    src := []string{"a", "b", "c"} 
    dst := []*string{} 
    for _, val := range src { 
     dst = append(dst, &val) 
    } 

    for i, s := range dst { 
     fmt.Printf("%v - %v - %p\n", i, *s, s) 
    } 

    //modify only contents of first index 
    *dst[0] = "hi val" 

    for i, s := range dst { 
     fmt.Printf("%v - %v - %p\n", i, *s, s) 
    } 
} 

>>>> 
0 - c - 0x1040a120 
1 - c - 0x1040a120 
2 - c - 0x1040a120 
0 - hi val - 0x1040a120 
1 - hi val - 0x1040a120 
2 - hi val - 0x1040a120 

後知恵で、これは明白ですが - for _, val - >:= < - range src - それはあなたがそれに気づいていない場合は、お尻であなたを噛まないので、したがって、この警告することができますすることができます。

PS。これはsrcのマップにも当てはまります。

4

@ RickyAの回答に追加します。

はあなたが何をする必要がありますしようとしていたものを達成するために:あなたはすでにいくつかの良い答えを得たので

for i := range src { 
    dst[i] = &src[i] 
} 
関連する問題