簡體   English   中英

Go 代碼報告更新切片的底層數組不正確?

[英]Go code is reporting incorrect underlying array for an updated slice?

我有以下代碼( Go Playground Example ),它定義了一個切片(在內部這將創建一個數組並將切片的指針設置為內存中的數組位置),然后向它附加一個新值......

s := []int{1, 2, 3, 4}

hdr := (*reflect.SliceHeader)(unsafe.Pointer(&s))
data := *(*[4]int)(unsafe.Pointer(hdr.Data))

fmt.Printf("slice:  %T\n\t%#v\n\tlen: %d\n\tcap: %d\n", s, s, len(s), cap(s))
fmt.Printf("hdr: %#v\n", hdr)   // &reflect.SliceHeader{Data:0x40e020, Len:4, Cap:4}
fmt.Printf("data: %#v\n", data) // [4]int{1, 2, 3, 4}

s = append(s, 5)

hdr = (*reflect.SliceHeader)(unsafe.Pointer(&s))
data = *(*[4]int)(unsafe.Pointer(hdr.Data))

fmt.Printf("slice:  %T\n\t%#v\n\tlen: %d\n\tcap: %d\n", s, s, len(s), cap(s))
fmt.Printf("hdr: %#v\n", hdr)   // &reflect.SliceHeader{Data:0x45e020, Len:5, Cap:8}
fmt.Printf("data: %#v\n", data) // [4]int{1, 2, 3, 4}

我在這段代碼中遇到的問題是最后一行,它表明雖然附加一個新值會導致底層數組被重新創建(因為它需要調整大小),但data變量報告的值似乎顯示了原始數組內容(例如它的長度為 4)而不是更新的內容。

即使我們從中提取Data字段的SliceHeader將底層數組的長度顯示為預期的更新長度為 5?

我在這里想念什么。 為什么最后一行不打印[8]int{1, 2, 3, 4, 5, 0, 0, 0}類的東西。

謝謝!

這是因為在 append 之后,您使用更新后的切片 header 中的數據指針,但您仍然將數據指針轉換為*[4]int ,一個指向長度為 4 的數組的指針。 除了 4 還能有什么長度?

這樣做是可以的,但您將只能訪問底層更大數組的前 4 個元素。 而是使用[8]int

data2 := *(*[8]int)(unsafe.Pointer(hdr.Data))
fmt.Printf("data: %#v\n", data2) // [8]int{1, 2, 3, 4, 5, 0, 0, 0}

這將是 output(在Go Playground上嘗試):

data: [8]int{1, 2, 3, 4, 5, 0, 0, 0}

暫無
暫無

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

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