指针其实跟变量一样, 只不过普通变量存放的是数值, 而指针变量存放的是数值的内存地址.
其中 & 符号表示对变量取地址, 得到一个指针; * 符号有 两种用法 , 如果 * 后面跟的是指针, 则表示对指针取值, 即得到指针指向的值; 如果如果 * 后面跟的是类型, 则表示一个指向该类型的 指针 .
Go 文档的一个栗子:
- func main() {
- i := 42 // 初始化一个值
- p := &i // &i 表示对变量 i 取地址, 并把地址赋给 p, 所以 p 是一个指针, 指向 i 的值
- fmt.Println("pointer", p) // pointer 0xc000020078
- fmt.Println("value", *p) //* 表示对指针取值, 即得到 p 指向的值, 为 42
- *p = 21 // 通过指针赋值
- fmt.Println(i) // 21
- var k *int // 这里的 k 是一个指针!!!
- }
注: Golang 的指针不能进行计算. 指针计算其实就是指针加减, 在 C 语言中, 是允许这样操作的, 比如我们知道 c 语言中的数组名其实就是该数组的首地址, 通过下标取值其实就是首地址的偏移, 即加减.
结构体
Golang 里面的结构体 (struct) 可以类比面对对象语言中的类.
就像类有类方法一样, Golang 也有结构体方法, 并且有带指针和不带指针的类方法. 它们的区别具体如下:
- type Rectangle struct {
- width int
- height int
- }
- func (r Rectangle) setWidth() {
- r.width = 100
- }
- func (r *Rectangle) setHeight() {
- r.height = 100
- }
- func main() {
- rec := Rectangle{width: 1, height: 1}
- rec.setWidth()
- fmt.Println(rec.width) // 仍然是 1
- rec.setHeight()
- fmt.Println(rec.height) // 变为 100
- }
通过上面的例子可以看到, 不带指针的方法(setWidth), 传递的参数 r 其实是 Rectangle 的一份拷贝, 所以即使在方法里面修改了 width 的值, 原有的结构体并不受影响; 而带指针的方法则相反.
官方文档也提到了这两者的区别:
Rectangle Rectangle
参考:
Should I define methods on values or pointers?
go struct 方法使用指针与不使用指针的区别? https://segmentfault.com/q/1010000012079161
来源: http://www.tuicool.com/articles/zE3y2qz