Go语言的批量相对来说比较简单一些,接下来我们学习一下吧
简介
Go语言的指针有三个概念需要明确一下:指针地址、指针类型及指针取值。任何的程序在载入到内存时,都会给它分配一下地址,而这个地址就是指针,保存这个地址的变量就称为指针变量。
Go语言中的指针是不能进行偏移和运算的,所以操作起来也比较简单,我们只需要记住两个符号就可以了:取地址(&
)、地址取值(*
)。
指针地址与类型
每个变量在运行的时候都会拥有一个地址,这个地址标识着变量所在的内存位置。Go语言使用&
符号对变量进行“取地址”的操作。Go语言中的值类型(如:int、float、bool、string、array、struct)都有对应的指针类型,比如int
的指针类型为*int
.
取一个变量的指针,语法如下:
ptr := &v
说明:
prt
- 接收变量指针地址的变量v
- 被取地址的变量
来个示例:
func main() {
a := 20
b := &a
fmt.Printf("a: %d, type: %T, ptr: %p\n", a, a, &a)
fmt.Printf("b: %d, type: %T, ptr: %p\n", *b, b, b)
fmt.Println(&b) // b同样也有自己的指针地址
}
输出:
a: 20, type: int, ptr: 0x14000016098
b: 20, type: *int, ptr: 0x14000016098
0x1400000e028
指针取值
对获取到的指针进行*
号操作,就是指针取值了,如下:
func main() {
a := 20
b := &a // 将变量a的地址保存在b变量中
fmt.Printf("type of b : %T\n", b) // 指针类型:*int
c := *b // 对指针进行取指操作
fmt.Printf("type of c : %T\n", c) // 值类型:int
fmt.Printf("value of c : %v\n", c) // 值为:20
}
new和make
上面我们学习了指针相关的知识,我们来看一下小例子:
func main() {
var a *int
*a = 200
fmt.Println(*a)
}
上面的小例子,会报panic
异常,原因是Go语言中引用类型的变量不仅要声明它,而且还有对它进行初始化(即分配内存空间,比如map
的使用),否则我们的值就没办法存储。而对值类型的声明不需要初始化,是因为它在声明的时候已经默认分配为内存空间了,比如基础数据类型。要分配空间就引出了今天要说的两个主角:new和make,它们两个都是内建函数,而且都是用来分配空间的,那么有什么区别呢?让我们来看一下吧~
new
new是一个内建的函数,格式如下:
func new(Type) *Type
说明:
Type
- 表示要分配内存的类型*Type
- 表示类型的指针,返回的是一个指向该类型内存地址的指针
new其实在实际开发中并不常用,来个小例子看一下吧:
func main() {
var a *int // 声明一个int类型的指针变量
a = new(int) // 对变量进行内存分配
*a = 20 // 对变量进行赋值,如果不赋值的话,它的值为该类型的默认值
fmt.Println(*a)
}
输出:
20
make
make也是用来分配内存的,不过它只用于slice
、map
及chan
这些类型,而它返回的是这些类型的本身,而不是指针类型的,因为这几个类型都是引用类型的,格式如下:
func make(t Type, size ...IntegerType) Type
make在实际开发中还是比较常用的,比较之前讲的map的初始化,来个小示例吧:
func main() {
var b map[string]int
b = make(map[string]int, 2)
b["score"] = 20
fmt.Println(b)
}
输入:
map[score:20]
总结一下两者的区别
- 两都是用来分配内存的。
- new是对基础类型进行内存分配的,内存对应的值为该类型的默认值,返回的是该类型的指针。
- make只用于
slice
、map
及chan
这些类型,返回的是它们本身。