[英]Convert slice of string to slice of pointer to string
我想將一個字符串切片轉換為指向字符串的指針切片
values1 := []string{"a", "b", "c"}
var values2 []*string
for _, v := range values1 {
fmt.Printf("%p | %T\n", v, v)
values2 = append(values2, &v)
}
fmt.Println(values2)
%!p(string = a)=>字符串
%!p(string = b)=>字符串
%!p(string = c)=>字符串
[0xc42000e1d0 0xc42000e1d0 0xc42000e1d0]
據我了解,
我的變量v
似乎是一個字符串,而不是指向字符串的指針。
因此,迭代時應從values1
復制v
。
顯然我不正確,因為v
仍然具有相同的地址0xc42000e1d0
。
如果v
值不是指針,如何改變它?
快速解決方案使用:
values1 := []string{"a", "b", "c"}
var values2 []*string
for i, _ := range values1 {
values2 = append(values2, &values1[i])
}
for .. range
子句中的迭代值分配給每個迭代。
該規范明確指出:
如賦值語句中所述,將迭代值分配給各個迭代變量。
這等效於:
var v string
v = string1
values[0] = &v
v = string2
values[1] = &v
etc...
變量v
仍然存在於相同的內存區域中,只是內容發生了變化。 因此, v
的地址永遠不變。
第一個版本不起作用,因為只有一個循環變量v
, 在每個迭代中它具有相同的地址 。 在每次迭代中都會分配循環變量,該變量會更改其值,但不會更改其地址,並且您會在每次迭代中附加相同的地址。
可能的解決方案是您提出的解決方案:在原始切片上附加適當切片元素的地址:
for i := range values1 {
values2 = append(values2, &values1[i])
}
這工作,但要注意values2
包含一個指向的支持數組地址values1
,這樣的支持數組values1
將被保存在內存中(會不會被回收)直到兩個values1
和values2
變量是不可到達的。 還要注意,修改values1
元素將間接影響values2
,因為values2
元素指向values1
元素。
另一種解決方案是創建臨時局部變量,並附加這些變量的地址:
for _, v := range values1 {
v2 := v
values2 = append(values2, &v2)
}
這樣,您的values2
切片將不會阻止values1
受到垃圾回收,並且在values1
修改值也不會反映在values2
,它們將是獨立的。
請參閱有關循環變量的相關問題:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.