Mengapakah Saya Tidak Boleh Mengubah Suai Nilai Jenis Mudah Melalui Kaedah Penerima Penunjuk dalam Go?

Barbara Streisand
Lepaskan: 2024-11-19 01:12:02
asal
272 orang telah melayarinya

Why Can't I Modify a Simple Type Value Through a Pointer Receiver Method in Go?

Mengubah suai Nilai Jenis Mudah melalui Kaedah Penerima Penunjuk dalam Go

Dalam Go, kami boleh mencipta jenis tersuai berdasarkan jenis asas dan melanjutkan fungsinya melalui kaedah penerima penunjuk. Walau bagaimanapun, terdapat persoalan biasa yang timbul apabila cuba mengubah suai nilai jenis mudah melalui kaedah penerima penunjuk.

Pertimbangkan contoh berikut:

package main

import (
    "fmt"
    "strconv"
)

type FooInt int

func (fi *FooInt) FromString(i string) {
    num, _ := strconv.Atoi(i)
    tmp := FooInt(num)
    fi = &tmp // Attempt to modify the pointer
}

func main() {
    var fi *FooInt
    fi.FromString("5")
    fmt.Printf("%v\n", fi) // Prints <nil>, not the expected 5
}
Salin selepas log masuk

Mengapakah penunjuk fi diisytiharkan dalam main() tidak menukar nilainya kepada alamat tmp?

Penjelasan

Apabila anda memanggil fungsi atau kaedah dalam Go, semua argumen, termasuk penerima , diluluskan sebagai salinan. Ini bermakna anda tidak boleh mengubah suai nilai penuding asal dari dalam fungsi/kaedah.

Dalam contoh di atas, fi dalam kaedah FromString ialah salinan penuding yang diisytiharkan dalam main(). Apabila anda menetapkan fi kepada alamat tmp, anda hanya menukar nilai salinan. Penunjuk asal kekal tidak berubah.

Penyelesaian

Terdapat tiga penyelesaian biasa untuk masalah ini:

1. Mengembalikan Penunjuk:

func (fi *FooInt) FromString(i string) *FooInt {
    num, _ := strconv.Atoi(i)
    tmp := FooInt(num)
    return &tmp
}

func main() {
    var fi *FooInt
    fi = fi.FromString("5")
    fmt.Printf("%v %v\n", fi, *fi) // Prints 0xc0000b4020 5
}
Salin selepas log masuk

2. Melepasi Hujah Penunjuk:

func (fi *FooInt) FromString(i string, p **FooInt) {
    num, _ := strconv.Atoi(i)
    tmp := FooInt(num)
    *p = &tmp
}

func main() {
    var fi *FooInt
    fi = new(FooInt) // Ensure non-nil receiver
    fi.FromString("5", &fi)
    fmt.Printf("%v %v\n", fi, *fi) // Prints 0xc0000b4020 5
}
Salin selepas log masuk

3. Memastikan Penerima Bukan Nihil:

func (fi *FooInt) FromString(i string) {
    num, _ := strconv.Atoi(i)
    *fi = FooInt(num)
}

func main() {
    var fi *FooInt
    fi = new(FooInt) // Ensure non-nil receiver
    fi.FromString("5")
    fmt.Printf("%v %v\n", fi, *fi) // Prints 0xc0000b4020 5
}
Salin selepas log masuk

Atas ialah kandungan terperinci Mengapakah Saya Tidak Boleh Mengubah Suai Nilai Jenis Mudah Melalui Kaedah Penerima Penunjuk dalam Go?. 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