Rumah >pembangunan bahagian belakang >Golang >Mengapakah Saya Tidak Boleh Mengubah Suai Nilai Jenis Mudah Menggunakan Penerima Penunjuk dalam Go?

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

Barbara Streisand
Barbara Streisandasal
2024-11-16 06:53:03327semak imbas

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>
}

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
    }
  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
    }
  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
    }

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!

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