猿问

指针解引用在 Go 中是如何工作的?

我正在浏览http://tour.golang.org/ 上的 golang 教程,并在示例 29 中尝试了一些东西


供您参考,原始示例复制到此处:


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() {

    fmt.Println(p, q, r, s)

}

这是非常基本的,展示了如何创建这个花哨的新结构的实例,Vertex. 但是,示例 28显示了通过指向顶点的指针来操作顶点,因此我稍微修改了示例,并且对输出感到惊讶。这是修改:


func main() {

    t := *q

    q.X = 4

    u := *q

    fmt.Println(p, q, r, s, t, u, t == u)

}

和输出:


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

令我惊讶的是它t不是 {4, 2},这似乎意味着更改q.X更改了q指向的结构的实例。来自 C/C++ 背景,这对我来说似乎是非常奇怪的行为。


那么,这里究竟发生了什么?为什么使用q.X = 4改变顶点不会传播到t?


肥皂起泡泡
浏览 179回答 1
1回答

收到一只叮咚

t := *q复制指向的结构体q。如果您想观察qthrough 的变化t,请坚持使用指针:var (&nbsp; &nbsp; p = Vertex{1, 2}&nbsp; // has type Vertex&nbsp; &nbsp; q = &Vertex{1, 2} // has type *Vertex&nbsp; &nbsp; r = Vertex{X: 1}&nbsp; // Y:0 is implicit&nbsp; &nbsp; s = Vertex{}&nbsp; &nbsp; &nbsp; // X:0 and Y:0)func main() {&nbsp; &nbsp; t := q&nbsp; &nbsp; q.X = 4&nbsp; &nbsp; u := *q&nbsp; &nbsp; fmt.Println(p, q, r, s, t, u, *t == u)}这会产生您可能正在寻找的输出。{1 2} &{4 2} {1 0} {0 0} &{4 2} {4 2} true我不确定你觉得什么特别奇怪。C 和 C++ 的行为方式相同。考虑以下:#include <iostream>struct Vertex{&nbsp; &nbsp; int x;&nbsp; &nbsp; int y;};std::ostream& operator<<(std::ostream& out, const Vertex& v){&nbsp; &nbsp; out << "{ " << v.x << ", " << v.y << " }";&nbsp;&nbsp; &nbsp; return out;}int main(){&nbsp; &nbsp; Vertex v = Vertex{1, 2};&nbsp; &nbsp; Vertex* q = &v;&nbsp; &nbsp; Vertex t = *q;&nbsp; &nbsp; q->x = 4;&nbsp; &nbsp; std::cout << "*q: " << *q << "\n";&nbsp; &nbsp; std::cout << " t: " << t << "\n";}此 C++ 代码的输出显示了相同的行为:*q: { 4, 2 }&nbsp;&nbsp;t: { 1, 2 }
随时随地看视频慕课网APP

相关分类

Go
我要回答