首頁 >後端開發 >Golang >為什麼 Go 中的直接切片轉換會為指標重複使用相同的記憶體位址?

為什麼 Go 中的直接切片轉換會為指標重複使用相同的記憶體位址?

Mary-Kate Olsen
Mary-Kate Olsen原創
2025-01-02 15:40:40457瀏覽

Why Does Direct Slice Conversion in Go Reuse the Same Memory Address for Pointers?

Go 切片和記憶體可重複使用性

在涉及 Go 指標的專案中出現了一個奇怪的問題。問題在於,當將一片結構物件轉換為一片介面時,第一個指標的記憶體位址在輸出中重複使用。

為了解決此問題,開發人員修改了轉換函數以使用額外的函數變量,產生了預期的輸出。

這提出了一個問題:為什麼原始解決方案失敗了?為了理解這一點,我們需要深入研究 Go 如何處理指標和切片。

在 Go 中,表達式 *coll 傳回切片頭,其中包含有關底層陣列、其長度和容量的資訊。存取切片的元素時,使用表達式 (*coll)[idx],它會傳回索引 idx 處元素的參考。

在原始解中,item 是 range 中的循環變數*科爾循環。此循環迭代切片標頭,將切片的每個元素指派給循環變數 item。但是,由於 item 是循環變量,因此它的記憶體位址在整個循環中保持不變。因此,當 &item 附加到輸出切片時,相同的記憶體位址會被多次添加,從而導致觀察到的行為。

修改後的解決方案在循環中將索引 idx 處的元素分配給局部變數 i。此變數與循環變數項具有不同的記憶體位址,因此,當將 &i 新增至輸出切片時,每個元素都有不同的記憶體位址。

為了說明循環變數之間記憶體位址的差異以及正在存取的元素,請考慮以下程式碼:

package main

import "fmt"

func main() {

    coll := []int{5, 10, 15}

    for i, v := range coll {
       fmt.Printf("This one is always the same; %v\n", &v)
       fmt.Println("This one is 4 bytes larger each iteration; %v\n", &coll[i])
    }
}

執行此程式碼將證明&v 對於循環的所有迭代都具有相同的記憶體位址,而&coll[i] 具有每次迭代都有不同的記憶體位址。

以上是為什麼 Go 中的直接切片轉換會為指標重複使用相同的記憶體位址?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn