每个变量都有一个地址,使用“&”操作符放在变量前面对变量进行取地址操作。
package main
import "fmt"
func main() {
var cat int = 1
var str string = "banana"
fmt.Printf("%p %p", &cat, &str)
}
输出结果:
0xc000018080 0xc000010250
看以下代码
ptr := &cat
fmt.Printf("%p , %T", ptr, ptr)
结果:
0xc00010c008 , *int
其中cat表示被取地址的变量,被取的地址的cat被ptr进行接收,ptr的类型为 *int
(因为cat的类型为int)称为T的指针类型,*
代表指针
每个变量都拥有地址,指针的值就是地址
可以使用* 操作代表指针取值
value := *ptr
fmt.Printf("%T\n", value)
fmt.Println(value)
结果:
int
1
由此可以看出:取地址符 &
和取值操作符 *
是一对互操作符,&
取出地址, *
根据地址取出地址指向的值。
变量、指针地址、指针变量、取地址、取值的相互关系和特性如下:
- 对变量进行取地址操作使用
&
操作符,可以获得这个变量的指针变量。 - 指针变量的值是指针地址。
- 对指针变量进行取值操作使用
*
操作符,可以获得指针变量指向的原变量的值
package main
import "fmt"
func swap(a, b *int) {
//取a指针的值 赋予t
t := *a
//将b指针的值赋予a
*a = *b
*b = t
}
func main() {
x, y := 1, 2
swap(&x, &y)
fmt.Println(x, y)
}
结果:
2 1
*
操作符作为右值时,意义是取指针的值,作为左值时,也就是放在赋值操作符的左边时,表示 a 指针指向的变量。其实归纳起来, *
操作符的根本意义就是操作指针指向的变量。当操作在右值时,就是取指向变量的值,当操作在左值时,就是将值设置给指向的变量
通过new()函数创建指针
import "fmt"
func main() {
str := new(string)
*str = "hello"
fmt.Println(*str)
}
结果:
hello
这里需要注意的是通过new()创建的指针,创建之后是已经开辟了内存空间的。而如果只是普通的声明指针类型,声明之后是nil。
即:
- 使用当一个指针被定义后而没有分配到任何变量时,它的值为nil
- new()函数可以创建一个对应类型的指针,创建过程会分配内存,被创建的指针指向默认值。