首頁  >  文章  >  後端開發  >  這些結構的幕後發生了什麼事? struct 會被複製嗎?

這些結構的幕後發生了什麼事? struct 會被複製嗎?

PHPz
PHPz轉載
2024-02-05 23:27:03821瀏覽

这些结构的幕后发生了什么? struct 会被复制吗?

問題內容

我不明白這段程式碼到底發生了什麼事。

接收方 func 在原始結構 user 上工作(因為指標),因此在 func 內部我們更改了原始 obj。但是結構地址也是原始的還是原始“a”的副本?

func main() {
    a := address{"freedom", "kyiv"}
    u := user{"valeriy", "zalyzhnyi", a}
    fmt.println(a)
    fmt.println(u)
    u.updatestreet("peremohy")

    fmt.println(a)
    fmt.println(u)
}

func (u *user) updatestreet(street string) {
    u.address.street = street
}

type user struct {
    firstname string
    lastname  string
    address   address
}

type address struct {
    street string
    city   string
}

這是我的輸出

{Freedom Kyiv}
{Valeriy Zalyzhnyi {Freedom Kyiv}}
{Freedom Kyiv}
{Valeriy Zalyzhnyi {Peremohy Kyiv}}

由此我了解到 u.address 已更改,而且我還看到“u”內的“a”與原始的 obj 不同。 那麼幕後和記憶體中究竟發生了什麼事? 根據輸出,這種行為對我來說是完全出乎意料的。 我期望由於指標的存在,我們在兩種情況下都使用原始物件(“a”和“u”)。第二次(在func 'update..' 之後)列印fmt.println(a) 將為我們提供{peremohy kyiv},因為第二次fmt.println(u) 為我們提供{valeriy zalyzhnyi {peremohy kyiv}}


正確答案


要了解幕後發生的情況,視覺化程式碼的作用可能會很有用:

a = address{}
u := user{address: a}

細分為:

| variable value        | memory address |
| a = address{}         | 0x000001       |
| u = user{}            | 0x000002       |
| u.address = copy of a | 0x000003       |

因此,您已為 1 個 user{} 實例和 2 個 address{} 實例分配了記憶體。第二個位址實例的值是第一個位址實例的精確副本(在建立副本時)。

現在,當您呼叫updatestreet 時,它是透過指標在u 上呼叫的,它不會建立user 實例的副本,而是對記憶體位址0x000002 進行操作,因此它實際上會對同一個a 變數進行操作。因此表達式:

u.address.street = "foo"

翻譯為:在記憶體位址 0x000002 中儲存的值上,存取名為 address 的字段,在該字段中,存取字段 street 並為其分配新值。讓我們將其映射到我們上面創建的表上:

0x000002 -> address (which is stored in 0x000003)
              |
              --> set street to "foo"

函數返回後,我們在記憶體中的相同位置仍然擁有與之前相同的對象,但是因為我們透過記憶體中的位址存取了a 的值,所以updatestreet 函數所做的更改已經完成為u 的值(因為我們使用了相同的記憶體位址)。

變數a 在賦值給u.address 時被複製,因此它的記憶體位址未知,或傳遞給updatestreet 函數,因此保持不變。

以上是這些結構的幕後發生了什麼事? struct 會被複製嗎?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:stackoverflow.com。如有侵權,請聯絡admin@php.cn刪除