簡體   English   中英

將字符串切片轉換為指向字符串的指針切片

[英]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將被保存在內存中(會不會被回收)直到兩個values1values2變量是不可到達的。 還要注意,修改values1元素將間接影響values2 ,因為values2元素指向values1元素。

另一種解決方案是創建臨時局部變量,並附加這些變量的地址:

for _, v := range values1 {
    v2 := v
    values2 = append(values2, &v2)
}

這樣,您的values2切片將不會阻止values1受到垃圾回收,並且在values1修改值也不會反映在values2 ,它們將是獨立的。

請參閱有關循環變量的相關問題:

為什么這兩個for循環變量會給我不同的行為?

Golang:使用循環切片/地圖范圍注冊多個路由

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM