先看一段代码, 人工运行一下, 看看自己能做对几题?
- package main
- import "fmt"
- func main() {
- var a int = 1
- var b *int = &a
- var c **int = &b
- var x int = *b
- fmt.Println("a =",a)
- fmt.Println("&a =",&a)
- fmt.Println("*&a =",*&a)
- fmt.Println("b =",b)
- fmt.Println("&b =",&b)
- fmt.Println("*&b =",*&b)
- fmt.Println("*b =",*b)
- fmt.Println("c =",c)
- fmt.Println("*c =",*c)
- fmt.Println("&c =",&c)
- fmt.Println("*&c =",*&c)
- fmt.Println("**c =",**c)
- fmt.Println("***&*&*&*&c =",***&*&*&*&*&c)
- fmt.Println("x =",x)
- }
符号 &** 的意思是对变量取地址
如: 变量 a 的地址是 & a
符号 * 的意思是对指针取值,
如:*&a, 就是 a 变量所在地址的值, 当然也就是 a 的值了
简单的解释
* 和 & 可以互相抵消 但是注意
[ *& ] 可以抵消掉, 但 [ &* ] 是不可以抵消的
a 和 *&a 是一样的, 都是 a 的值, 值为 1 (因为 *& 互相抵消掉了)
a 和 *&*&*&*&a 是一样的, 都是 1 (因为 4 个 *& 互相抵消掉了)
因为有
var b *int = &a
所以
a 和 *&a 和 * b 是一样的, 都是 a 的值, 值为 1 (把 b 当做 & a 看)
因为有
var c **int = &b
所以
**c 和 **&b 是一样的, 把 & 约去后
会发现 **c 和 b 是一样的 (从这里也不难看出, c 和 b 也是一样的)
又因为上面得到的 & a 和 b 是一样的 所以 **c 和 & a 是一样的,
再次把 *& 约去后 **c 和 a` 是一样的, 都是 1
你也试着运行一下吧 ~
- ## 运行结果
- $ go run main.go
- a = 1
- &a = 0xc200000018
- *&a = 1
- b = 0xc200000018
- &b = 0xc200000020
- *&b = 0xc200000018
- *b = 1
- c = 0xc200000020
- *c = 0xc200000018
- &c = 0xc200000028
- *&c = 0xc200000020
- **c = 1
- ***&*&*&*&c = 1
- x = 1
两个符号抵消顺序
*& 可以在任何时间抵消掉, 但 &* 不可以被抵消的, 因为顺序不对
- fmt.Println("*&a\t=\t",*&a) // 成功抵消掉, 打印出 1, 即 a 的值
- fmt.Println("&*a\t=\t",&*a) // 无法抵消, 会报错
来源: https://juejin.im/post/5c9480d9f265da60c95b6d4d