Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Mengapakah Saya Tidak Boleh Mengubah Suai Nilai Jenis Mudah Melalui Kaedah Penerima Penunjuk dalam Go?

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

Barbara Streisand
Barbara Streisandasal
2024-11-19 01:12:02268semak imbas

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
}

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
}

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
}

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
}

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!

Kenyataan:
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