指针类型
取址符:& 取值符: *
var x = 10 // x 是整型变量
//用 &x 取出 变量x 内存地址
fmt.Println("x的内存地址:",&x) // x的内存地址: 0xc0000ae008
// 定义 int 类型的指针变量
var p *int
p = &x // 将地址值赋值给的变量称为指针变量
fmt.Println("p的值:",p) // p的值: 0xc0000ae008
fmt.Println("p的地址:",&p) // p的地址: 0xc0000b2020
fmt.Println("p的地址对应的值:",*p) // p的地址对应的值: 10
再次说明:
//1. p 定义的是指针类型,也是一种数据类型,它存储的是内存地址
//2. *数据类型: 这个数据类型是取决于你的内存地址里面放的值的数据类型。如果你的值是int类型,那么指针类型想拿这个值的地址,就要定义为 *int 类型,如果是你的值是 string 类型,那么就定义为*string,依次类推。
//例如:int类型的
var x int = 10 // x 是整型变量
var p *int // 因为x的数据类型是int型,所以指针类型也是 int型
p = &x
fmt.Println(p, reflect.TypeOf(p)) // 0xc0000b0008 *int
//例如:string类型
s := "hello world"
var p *string
p = &s // 当然你嫌麻烦:直接写 p := &s
内存中值变换
Go语言:当使用等号=将一个变量的值赋给另一个变量时,如 j = i ,实际上是在内存中将 i 的值进行了拷贝,可以通过 &i 获取变量 i 的内存地址。此时如果修改某个变量的值,不会影响另一个。
var x int
x = 10
fmt.Println("x=10的内存地址:",&x) //x=10的内存地址: 0xc000018070
x = 100
fmt.Println("x=100的内存地址:",&x) // x=100的内存地址: 0xc000018070
从上面例子可以看出来,x 的变量一旦声明就在内存中占用一定的空间,不会因为值的变化,重新开辟空间,因为这个内存地址已经分配出来了,所以变量 x 的值只能在 int 的数据范围内:
Python语言:内存地址重新指向,之前没有引用会垃圾回收站自动回收。