Rumah  >  Artikel  >  pembangunan bahagian belakang  >  ## Mengapakah Saya Boleh Menghubungi Kaedah Penunjuk pada Nilai dalam Go?

## Mengapakah Saya Boleh Menghubungi Kaedah Penunjuk pada Nilai dalam Go?

Mary-Kate Olsen
Mary-Kate Olsenasal
2024-10-25 07:55:02770semak imbas

##  Why Can I Call a Pointer Method on a Value in Go?

Kaedah Penerima Memanggil Kekeliruan Sintaks dalam Go

Apabila meneroka perbezaan antara penunjuk dan nilai untuk penerima, adalah diperhatikan bahawa kaedah nilai boleh digunakan pada kedua-dua penunjuk dan nilai, manakala kaedah penunjuk adalah terhad kepada penunjuk sahaja. Sekatan ini berpunca daripada keupayaan kaedah penuding untuk mengubah suai penerima, mengakibatkan pengubahsuaian dibuang jika digunakan pada salinan nilai.

Walau bagaimanapun, contoh kod yang mempamerkan kaedah penunjuk yang dipanggil pada nilai menyebabkan kekeliruan. Kodnya adalah seperti berikut:

<code class="go">package main

import (
    "fmt"
    "reflect"
)

type age int

func (a age) String() string {
    return fmt.Sprintf("%d year(s) old", int(a))
}

func (a *age) Set(newAge int) {
    if newAge >= 0 {
        *a = age(newAge)
    }
}

func main() {
    var vAge age = 5
    pAge := new(age)

    fmt.Printf("Type information:\n\tvAge: %v\n\tpAge: %v\n", reflect.TypeOf(vAge),
        reflect.TypeOf(pAge))

    fmt.Printf("vAge.String(): %v\n", vAge.String())
    fmt.Printf("vAge.Set(10)\n")
    vAge.Set(10)
    fmt.Printf("vAge.String(): %v\n", vAge.String())

    fmt.Printf("pAge.String(): %v\n", pAge.String())
    fmt.Printf("pAge.Set(10)\n")
    pAge.Set(10)
    fmt.Printf("pAge.String(): %v\n", pAge.String())
}</code>

Walaupun dokumentasi menyatakan bahawa ia tidak sepatutnya boleh dilakukan, kod ini menyusun dan berjalan tanpa ralat. Jadi, apakah yang menyebabkan ketidakkonsistenan yang jelas ini?

Jawapannya terletak dalam konsep nilai yang boleh ditangani. Spesifikasi Go mentakrifkan bahawa "Panggilan kaedah x.m() adalah sah jika set kaedah (jenis) x mengandungi m dan senarai argumen boleh diberikan kepada senarai parameter m." Selain itu, "Jika x boleh dialamatkan dan set kaedah &x mengandungi m, x.m() ialah singkatan untuk (&x).m()."

Dalam kes ini, vAge boleh dialamatkan, bermakna ia mempunyai alamat memori yang sah . Apabila memanggil vAge.Set(), pengkompil mengenali bahawa kaedah penerima penunjuk Set() juga boleh digunakan menggunakan alamat nilai, yang bersamaan dengan (&vAge).Set().

Atas ialah kandungan terperinci ## Mengapakah Saya Boleh Menghubungi Kaedah Penunjuk pada Nilai 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