2 回答

TA貢獻(xiàn)1875條經(jīng)驗 獲得超5個贊
首先,如果你還沒有,你應(yīng)該閱讀這篇關(guān)于 slice internals 的官方博客文章。那應(yīng)該清除一切。
現(xiàn)在訪問的底層數(shù)組,你可以使用的組合reflect和unsafe。特別是,reflect.SliceHeader 包含一個Data字段,該字段包含一個指向切片底層數(shù)組的指針。
改編自unsafe包文檔的示例:
s := []int{1, 2, 3, 4}
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&s))
data := *(*[4]int)(unsafe.Pointer(hdr.Data))

TA貢獻(xiàn)2037條經(jīng)驗 獲得超6個贊
就像一個提示,回答你的第二個問題。從Go 1.17開始,你可以這樣做
(*[2]int)(numSlice)
package main
import (
"fmt"
)
func main() {
nums := [3]int{1, 2, 3}
numSlice := nums[:2]
underArr1 := (*[2]int)(numSlice)
fmt.Println(&underArr1[0]) //0xc000016018
numSlice = append(numSlice, 10)
underArr2 := (*[3]int)(numSlice)
fmt.Println(&underArr2[0]) //0xc000016018 - same
fmt.Println(nums) // [1 2 10]
numSlice = append(numSlice, 20)
underArr3 := (*[3]int)(numSlice)
fmt.Println(&underArr3[0]) //0xc000078030 - different
fmt.Println(cap(numSlice)) // 6
}
老實說,你不必轉(zhuǎn)換為數(shù)組指針來查看地址,我只是為了回答你的第二個問題。
該行為確實是您描述的方式。當(dāng)您追加 時10,您的底層數(shù)組中仍然剩下一個字段(因為它的長度是 3,但是您的 numSlice 是 2),即使它當(dāng)前被 a 占用3,它也可以使用,并被3覆蓋10。
當(dāng)您附加 a 時20,沒有剩余的字段,因此它會創(chuàng)建一個新的底層數(shù)組(很可能有 6 個字段長,兩倍大)并將原始數(shù)組中的所有數(shù)據(jù)復(fù)制到那里,并將指針移動到該數(shù)組。
- 2 回答
- 0 關(guān)注
- 467 瀏覽
添加回答
舉報