Go 指针要点

Posted on Jun 21, 2020

关键

  • 变量是包含值的存储
  • 指针的值是变量的地址

Go 语言的变量都拥有地址,而指针是一个变量,它的值是另外一个变量的地址。当我们说整型指针时,我们指的是一类型的指针。考虑下面的代码片段:

x := 1
p := &x         // p, 类型 *int, 指向 x
fmt.Println(*p) // "1"
*p = 2          // 相当于 x = 2
fmt.Println(x)  // "2"

操作符 & 作用于变量 x,产生了指针 p,p 的类型是 *int,可以发现其中 int 就是 x 的类型;操作符 * 作用于 p,检索了 p 指向的变量 x,能够读写 x 的值,但是这到底是什么意思?下图是一个很好的类比:

goPointer.png

左边为变量,中间为地址 (试着打印一下 p),右边为值。当执行了 p := &x 后,*p 是 x 的别名,故赋新值给 *p 也就更改了 x 的值。为什么指针还需要绑定类型?出于类型安全考虑,如果把上面代码的 *p = 2 替换成 *p = "two",那么编译不通过。

畅想

  • Go 函数调用的参数传递是值传递,值可能是地址,拷贝地址往往更高效,且能操纵指向的变量的值或引用的数据结构。
  • Java 把指针 (Pointer)伪装成引用(Reference),创建一个对象,则产生了这个对象的引用。
  • Java 方法调用的参数传递估计是值传递,只不过原始类型 (primitive type)赋予的是原值而引用类型 (reference type)赋予的是地址。

本文首发于 https://h2cone.github.io/

参考