指针在C语言中是很让人头疼的东西,因为其可以进行偏移和运算操作,如果操作不当,很可能会访问到非法、不安全的内存空间,从而导致程序的异常退出
但是在Go语言中,不允许指针进行偏移和运算,是安全指针

Go语言中的指针

任何程序在运行后,在内存中都会有他们的数据,也就是指针
普通变量存的可能是数字或者字符串等等数据
指针变量中存的则是内存地址

go语言中的指针,我们只需要记住两个运算

  • 取地址:&
  • 取值:*

指针地址和指针变量

这一部分内容和C语言中基本相同

  1. func main() {
  2. a := 10
  3. b := &a
  4. fmt.Printf("a:%d ptr:%p\n", a, &a) // a:10 ptr:0xc00001a078
  5. fmt.Printf("b:%p type:%T\n", b, b) // b:0xc00001a078 type:*int
  6. fmt.Println(&b) // 0xc00000e018
  7. }

指针取值

在对普通变量使用&符号可以得到这个变量对应的指针变量
而对指针变量使用*符号可以得到对应地址中的内容

内存分配

  1. func main() {
  2. var a *int
  3. *a = 100
  4. fmt.Println(*a)
  5. var b map[string]int
  6. b["沙河娜扎"] = 100
  7. fmt.Println(b)
  8. }

上述代码运行后会触发panic
原因是定义变量时没有进行初始化,也就是没有分配对应的内存空间
而在Go中,要分配内存就要使用makenew

new

函数原型如下:

  1. func new(Type) *Type

其中,

  • Type:表示返回什么类型的指针
  • *Type:表示分配好的内存指针

对上述代码修改如下,即可正常运行:

  1. func main() {
  2. var a *int
  3. a = new(int)
  4. *a = 10
  5. fmt.Println(*a)
  6. }

make

make和new一样,也是用来进行内存分配的。但相对于new来说,它只用于slicemap以及channel的内存创建,并且返回的类型也是这三个类型本身,而不是其指针类型,函数原型如下:

  1. func make(t Type, size ...IntegerType) Type

对于上述错误代码,修改如下即可正常运行:

  1. func main() {
  2. var b map[string]int
  3. b = make(map[string]int, 10)
  4. b["沙河娜扎"] = 100
  5. fmt.Println(b)
  6. }

new和make的区别

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