首頁 >後端開發 >Golang >為什麼我的 Go Struct Setter 函數沒有修改原始結構?

為什麼我的 Go Struct Setter 函數沒有修改原始結構?

Mary-Kate Olsen
Mary-Kate Olsen原創
2024-12-21 10:00:17700瀏覽

Why Doesn't My Go Struct Setter Function Modify the Original Struct?

了解結構體類型的 Setter

在 Go 中,可以透過 setter 函數修改結構體。但是,在對結構類型使用 setter 時,某些行為可能是無法預料的。考慮以下範例:

package main

import "fmt"

type T struct { Val string }

// this setter seems not to work
func (t T) SetVal(s string) {
    t.Val = s
}

// this setter, using ptr to T, seems to work ok
func (t *T) SetVal2(s string) {
    (*t).Val = s
}

func main() {
    v := T{"abc"}
    fmt.Println(v)        // prints {abc}
    v.SetVal("pdq")
    fmt.Println(v)        // prints {abc}, was expecting {pdq}!
    v.SetVal2("xyz")
    fmt.Println(v)        // prints {xyz}!
}

問題出現了:為什麼 SetVal 函數沒有如預期修改原始結構?

理解值語意

主要區別在於結構體如何傳遞給函數。當以值傳遞結構體時(如 SetVal),會在函數內建立該結構體的副本。函數內所做的任何變更只會影響此暫存副本,而原始結構保持不變。

但是,當透過指標傳遞結構時(如 SetVal2 中),函數可以存取記憶體中的原始結構。函數內所做的任何更改都將直接反映在原始結構中。

價值語意證明

這可以透過列印所涉及結構的記憶體位址來說明:

package main

import "fmt"

type T struct { Val string }

func (t T) SetVal(s string) {
    fmt.Printf("Address of copy is %p\n", &t)
}

func (t *T) SetVal2(s string) {
    fmt.Printf("Pointer argument is %p\n", t)
}

func main() {
    v := T{"abc"}
    fmt.Printf("Address of v is %p\n", &v)
    v.SetVal("pdq")
    v.SetVal2("xyz")
}

此程式碼將產生輸出類似於:

Address of v is 0xf840001290
Address of copy is 0xf8400013e0
Pointer argument is 0xf840001290

注意,列印的第一個和第三個位址是相同的,表示它們引用相同的結構體。然而,第二個位址不同,代表在 SetVal 中建立的暫存副本。

以上是為什麼我的 Go Struct Setter 函數沒有修改原始結構?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

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