doumou1864 2018-12-05 10:13
浏览 28
已采纳

为什么指针类型的行为与结构类型不同?

I have this fragment of Go code where I'm trying to change the values of a regular int and an int in a struct using two functions f and f2 respectively. I don't understand why I need to do *i to change the value of the int but I don't need to do that when I change the value of X in the struct.

type Point struct {
    X int
}

func t(i *int) {
    *i = 20
}

func t2(p *Point) {
    p.X = 200
}

func main() {
    g := 30
    t(&g)
    fmt.Println(g)

    p := Point{3}
    t2(&p)
    fmt.Println(p)
}
  • 写回答

2条回答 默认 最新

  • dprntkxh703029 2018-12-05 10:48
    关注

    The easiest way to think about both functions is that in the t2 function, you're changing a field of a struct, using a pointer to the underlying struct. In the t function, you're changing the entire underlying object (the int).

    In reality, the fact that you can write p.X is actually just a nicety. In languages like C, you could only use p.X if you were operating on a non-pointer variable. For pointers, you had to either use p->X denoting you were accessing a field using indirection, or indeed dereference the pointer ((*p).X).

    Internally, go still does the same thing, it just allows you to omit the explicit dereferencing, and it eliminates the need for an indirection operator.

    Both functions, however, are not equivalent. Point is a struct, with one or more fields. The other type is *int, an int is a single scalar value. To make t2 equivalent (and reassign the entire underlying object), you'll have to change the code to be identical to what you have to do in case of *int:

    func t2(p *Point) {
        *p = Point{
             X: 200,
             Y: p.Y,
         }
    }
    

    As per comment below: the TL;DR version is that you don't have to explicitly dereference a pointer to a struct type if you access one of its fields. You had to do that in C/C++, but the go compiler takes care of that for you. It works out you're using a variable that is a pointer type and compiles p.X in the same way that a C compiler would compile p->X. Therefore, you don't need to dereference p explicitly.

    You would still have to write *p.X if you declared Point as:

    type Point struct {
        X *int
    }
    

    Because the expression p.X evaluates to an operand of type *int, which needs to be treated accordingly.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 抖音咸鱼付款链接转码支付宝
  • ¥15 ubuntu22.04上安装ursim-3.15.8.106339遇到的问题
  • ¥15 求螺旋焊缝的图像处理
  • ¥15 blast算法(相关搜索:数据库)
  • ¥15 请问有人会紧聚焦相关的matlab知识嘛?
  • ¥15 网络通信安全解决方案
  • ¥50 yalmip+Gurobi
  • ¥20 win10修改放大文本以及缩放与布局后蓝屏无法正常进入桌面
  • ¥15 itunes恢复数据最后一步发生错误
  • ¥15 关于#windows#的问题:2024年5月15日的win11更新后资源管理器没有地址栏了顶部的地址栏和文件搜索都消失了