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
Mary-Kate Olsenasal
2024-12-08 12:53:11304semak imbas

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

Menjalankan kod ini menghasilkan hasil yang mengejutkan:

{1 2} &{4 2} {1 0} {0 0} {1 2} {4 2} false

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

Kod C ini menghasilkan tingkah laku yang sama:

*q: { 4, 2 }
t: { 1, 2 }

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

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!

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