Rumah > pembangunan bahagian belakang > Golang > Mengapa Penyahrujukan Penunjuk dalam Go tidak mengubah suai Nilai Asal?

Mengapa Penyahrujukan Penunjuk dalam Go tidak mengubah suai Nilai Asal?

Mary-Kate Olsen
Lepaskan: 2024-12-08 12:53:11
asal
310 orang telah melayarinya

Why Doesn't Dereferencing a Pointer in Go Modify the Original Value?

Penyahrujukan Penunjuk dalam Go: Apa Yang Berlaku?

Apabila mendalami dunia pengaturcaraan dalam Go, anda mungkin menjumpai gelagat menarik yang berkaitan dengan penyahrujukan penunjuk, terutamanya apabila bekerja dengan struct. Pertimbangkan contoh berikut:

package main

import "fmt"

type Vertex struct {
    X, Y int
}

var (
    p = Vertex{1, 2}  // has type Vertex
    q = &Vertex{1, 2} // has type *Vertex
    r = Vertex{X: 1}  // Y:0 is implicit
    s = Vertex{}      // X:0 and Y:0
)

func main() {
    t := *q
    q.X = 4
    u := *q
    fmt.Println(p, q, r, s, t, u, t == u)
}
Salin selepas log masuk

Menjalankan kod ini menghasilkan hasil yang mengejutkan:

{1 2} &{4 2} {1 0} {0 0} {1 2} {4 2} false
Salin selepas log masuk

Anda mungkin menjangka t akan berubah kepada {4, 2} selepas mengubah q.X, tetapi ini tidak berlaku. Apakah sebab bagi tingkah laku ini?

Penyahrujukan Penunjuk Dijelaskan

Kunci untuk memahami perkara ini ialah penyahrujukan penunjuk. Dalam Go, apabila anda menyahrujuk penunjuk (cth., *q), anda membuat salinan nilai yang ditunjukkannya. Jadi, t := *q membuat salinan berasingan struct Vertex yang dirujuk oleh q.

Contoh 28's Modification Dijelaskan:

Dalam contoh anda yang diubah suai, apabila anda menetapkan q.X = 4, anda hanya mengubah suai struct yang ditunjuk oleh q. Memandangkan t ialah salinan, ia mengekalkan nilai asalnya.

Membandingkan Go dan C/C

Anda menyebut tingkah laku yang kelihatan pelik dari perspektif C/C. Walau bagaimanapun, C/C berkelakuan serupa. Pertimbangkan contoh ini:

#include <iostream>

struct Vertex
{
    int x;
    int y;
};

int main()
{
    Vertex v = Vertex{1, 2};
    Vertex* q = &v;
    Vertex t = *q;
    q->x = 4;
    std::cout << "*q: " << *q << "\n";
    std::cout << " t: " << t << "\n";
}
Salin selepas log masuk

Kod C ini menghasilkan tingkah laku yang sama:

*q: { 4, 2 }
t: { 1, 2 }
Salin selepas log masuk

Kesimpulan

Ringkasnya, apabila anda tidak merujuk penunjuk dalam Go, anda' mencipta semula salinan nilai asas. Untuk melihat perubahan yang dibuat melalui penuding, anda mesti menggunakan penuding itu sendiri, seperti dalam contoh yang diubah suai:

func main() {
    t := q
    q.X = 4
    u := *q
    fmt.Println(p, q, r, s, t, u, *t == u)
}
Salin selepas log masuk

Ini akan menghasilkan output dijangka {1 2} &{4 2} {1 0} {0 0} {4 2} {4 2} benar.

Atas ialah kandungan terperinci Mengapa Penyahrujukan Penunjuk dalam Go tidak mengubah suai Nilai Asal?. 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