Rumah > pembangunan bahagian belakang > Golang > Mengapa Fungsi Penetap Go Struct Saya Tidak Mengubah Suai Struktur Asal?

Mengapa Fungsi Penetap Go Struct Saya Tidak Mengubah Suai Struktur Asal?

Mary-Kate Olsen
Lepaskan: 2024-12-21 10:00:17
asal
698 orang telah melayarinya

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

Memahami Penetap untuk Jenis Struktur

Dalam Go, struct boleh diubah suai melalui fungsi setter. Walau bagaimanapun, tingkah laku tertentu boleh tidak dijangka apabila menggunakan penetap untuk jenis struct. Pertimbangkan contoh berikut:

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}!
}
Salin selepas log masuk

Timbul persoalan: mengapa fungsi SetVal tidak mengubah suai struktur asal seperti yang dijangkakan?

Memahami Semantik Nilai

Perbezaan utama terletak pada cara struct dihantar ke fungsi. Apabila menghantar struct mengikut nilai (seperti dalam SetVal), salinan struct dibuat dalam fungsi. Sebarang perubahan yang dibuat dalam fungsi hanya akan menjejaskan salinan sementara ini, meninggalkan struct asal tidak berubah.

Walau bagaimanapun, apabila menghantar struct dengan penuding (seperti dalam SetVal2), fungsi mendapat akses kepada struct asal dalam memori. Sebarang perubahan yang dibuat dalam fungsi akan dicerminkan secara langsung dalam struct asal.

Semantik Bukti Nilai

Ini boleh digambarkan dengan mencetak alamat memori bagi struct yang terlibat :

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")
}
Salin selepas log masuk

Kod ini akan menghasilkan output menyerupai:

Address of v is 0xf840001290
Address of copy is 0xf8400013e0
Pointer argument is 0xf840001290
Salin selepas log masuk

Perhatikan bahawa alamat pertama dan ketiga yang dicetak adalah sama, menunjukkan bahawa ia merujuk kepada struct yang sama. Walau bagaimanapun, alamat kedua adalah berbeza, mewakili salinan sementara yang dibuat dalam SetVal.

Atas ialah kandungan terperinci Mengapa Fungsi Penetap Go Struct Saya Tidak Mengubah Suai Struktur Asal?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:php.cn
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Artikel terbaru oleh pengarang
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan