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

Barbara Streisand
Lepaskan: 2024-11-16 06:53:03
asal
238 orang telah melayarinya

Why Can't I Modify a Simple Type's Value Using a Pointer Receiver in Go?

Bagaimana untuk Mengubah Suai Nilai Jenis Mudah melalui Penerima Penunjuk dalam Go?

Dalam Go, penerima penunjuk dalam kaedah membenarkan anda mengubah suai nilai asal sesuatu struct. Walau bagaimanapun, ini tidak terpakai kepada jenis mudah. Soalan ini menyelidiki mengapa pengubahsuaian sedemikian tidak berfungsi dan memberikan penyelesaian.

Masalah

Pertimbangkan kod ini:

package main

import (
    "fmt"
    "strconv"
)

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

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

Di sini, anda menjangkakan fungsi FromString untuk menetapkan nilai fi kepada 5. Tetapi ia mencetak , menunjukkan penunjuk nol.

Memahami Gelagat

Dalam Go, argumen fungsi/kaedah, termasuk penerima, adalah salinan nilai asal. Akibatnya, pengubahsuaian dalam fungsi hanya menjejaskan salinan.

Malah untuk penunjuk, penerima adalah salinan penuding asal, bukan penuding sebenar itu sendiri. Oleh itu, pengubahsuaian yang dibuat kepada nilai penerima tidak akan menjejaskan penunjuk asal.

Penyelesaian

Untuk menyelesaikannya, terdapat beberapa pilihan:

  1. Kembalikan Penunjuk yang Diubah Suai:

    • Ubah suai fungsi untuk mengembalikan penuding yang diubah suai dan berikannya kepada penuding asal.
    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. Lepaskan Penunjuk untuk Ubah Suai:

    • Lepaskan penunjuk bukan nol daripada jenis yang diingini kepada fungsi dan ubah suai nilainya.
    func (fi *FooInt) FromString(i string, p **FooInt) {
        num, _ := strconv.Atoi(i)
        tmp := FooInt(num)
        *p = &tmp
    }
    
    func main() {
        var fi *FooInt
        fi.FromString("5", &fi)
        fmt.Printf("%v %v\n", fi, *fi) // Prints 0xc0000b4020 5
    }
    Salin selepas log masuk
  3. Pastikan Penerima Bukan Nihil:

    • Awalkan penerima kepada nilai bukan nol sebelum memanggil kaedah, jadi runcing nilai boleh diubah suai.
    func (fi *FooInt) FromString(i string) {
        num, _ := strconv.Atoi(i)
        *fi = FooInt(num)
    }
    
    func main() {
        fi := new(FooInt) // Initialize to non-nil
        fi.FromString("5")
        fmt.Printf("%v %v\n", fi, *fi) // Prints 0xc0000b4020 5
    }
    Salin selepas log masuk

Dengan menggunakan salah satu daripada penyelesaian ini, anda boleh mengubah suai nilai jenis ringkas dengan berkesan menggunakan penerima penunjuk.

Atas ialah kandungan terperinci Mengapakah Saya Tidak Boleh Mengubah Suai Nilai Jenis Mudah Menggunakan 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