跳到主要内容位置

Golang 的指针

1. 指针简介

概要

Go 语言中的指针不能进行偏移和运算,因此 Go 语言中的指针操作非常简单,我们只需要记住两个符号:&(取地址)和*(根据地址取值)。所以 Golang 的指针也算是安全指针

指针类型

  1. 每个变量在运行时都拥有一个地址,这个地址代表变量在内存中的位置。
  2. Go 语言中使用&字符放在变量前面对变量进行“取地址”操作。
  3. Go 语言中的值类型(int、float、bool、string、array、struct)都有对应的指针类型,如:int、int64、*string 等。
//小案例 快速了解指针
func main() {
a := 10
b := &a
fmt.Printf("a:%d ptr:%p\n", a, &a) // a:10 ptr:0xc00001a078
fmt.Printf("b:%p type:%T\n", b, b) // b:0xc00001a078 type:*int
fmt.Println(&b) // 0xc00000e018
}

2.取地址与取值操作

总结
  1. 取地址操作符&和取值操作符*是一对互补操作符,
  2. &取出地址,*根据地址取出地址指向的值。
func main() {
//指针取值
a := 10
b := &a // 取变量a的地址,将指针保存到b中
fmt.Printf("type of b:%T\n", b)
c := *b // 指针取值(根据指针去内存取值)
fmt.Printf("type of c:%T\n", c)
fmt.Printf("value of c:%v\n", c)
}

/*
结果如下:

type of b:*int
type of c:int
value of c:10
*/

3.new 与 make

3.1 new 函数

new()函数

new 函数不太常用,使用 new 函数得到的是一个类型的指针, 一般用于intstringboolstruct这些值类型数据 并且该指针对应的值为该类型的零值。举个例子:

func main() {
a := new(int)
b := new(bool)
fmt.Printf("%T\n", a) // *int
fmt.Printf("%T\n", b) // *bool
fmt.Println(*a) // 0
fmt.Println(*b) // false
}


func main() {
var a *int//对a进行了声明(没有初始化,还不能赋值)
a = new(int)//对A进行初始化
*a = 10
fmt.Println(*a)
}

3.1 make 函数

make()函数

make 也是用于内存分配的,区别于 new,它只用于 slicemap 以及 channel 的内存创建,而且它返回的类型就是这三个类型本身,而不是他们的指针类型,因为这三种类型就是引用类型,所以就没有必要返回他们的指针了。

func make(t Type, size ...IntegerType) Type
//make的签名函数格式


func main() {
var b map[string]int
b = make(map[string]int, 10)
b["沙河娜扎"] = 100
fmt.Println(b)
}
//小案例

3.3 ⚡️ 两者对比 ⚡️

  1. 二者都是用来做内存分配的。
  2. make 只用于 slice、map 以及 channel 的初始化,返回的还是这三个引用类型本身;
  3. 而 new 用于类型的内存分配,并且内存对应的值为类型零值,返回的是指向类型的指针。