golang指针理解

118 阅读3分钟

指针

概念

  • 指针是一种存储变量内存地址的变量,一个指针变量指向了一个值的内存地址。
  • golang中,指针不能进行运算,也不可以进行指针类型转换

作用

通过指针我们可以直接访问和修改变量的值,而不需要拷贝变量本身,这样能提高程序的效率。 golang中指针的作用有一下几点

  • 传递变量的地址:指针可以做为函数参数,讲变量的地址穿点给函数,这样函数就可以直接修改变量的值

  • 动态分配内存:通过指针可以运行时动态分配内存,这样程序就可以根据需要动态地创建和销毁变量

  • 访问复杂数据结构:指针可以用于访问复杂的数据结构,如链表,树等

  • 函数返回值:指针可以作为函数的返回值,这样函数就可以返回一个只想变量的指针,而不是变量本身,这样可以避免变量拷贝和内存分配的开销。

  • Go 语言中的函数传参都是值拷贝,当我们想要修改某个变量的时候,我们可以创建一个指向该变量地址的指针变量。传递数据使用指针,而无须拷贝数据

操作

Go 语言中的指针操作非常简单,只有记住两个符号就可以了。

  • &(取地址)
  • *(根据地址取值)

操作中对应的的三个概念:

  • 指针地址 : &a 取到的数据是指针地址 (指针变量的值是指针地址)

  • 指针类型 :Go 语言常用的值类型 (string、int、array、struct、float、bool )都会有对应的指针类型。如:string、 int、*int64 等。(需要明白它是一个变量其次它有对应类型)

  • 指针取值 : *a 取到的是指针地址指向的数据内容

指针数组

指针数组(数组元素是指针类型)

# 语法: var 数组名 [下标]*类型

var nums [2]*int
a, b := 100, 200
nums[0] = &a
nums[1] = &b

// 输出指针数组内容 :[0xc000018098 0xc0000180b0]
fmt.Println(nums)
// 输出指针数据内存地址对应的值 :100
fmt.Println(*nums[0])


# 定义指针,指向切片,也就是这个指针保存了切片的地址,可以通过地址修改切片中的值。
s := []int{100, 200, 300, 400}
var p *[]int = &s
//将切片中的300修改为366666
(*p)[2] = 3666666

# 定义指针,指向结构体

var zhangsan Class = Class{100, "zhangsan", 10}
var p *Class = &zhangsan
fmt.Println((*p).age)

# 结构体指针作为函数参数,在函数中修改结构体内容,会影响到原来的值,因为指针变量存储的是指针地址,操作的也是同一个地址指向的内容。




空指针

当一个指针被定义后没有分配到任何变量时,它的值为 nil (空指针)。 nil在概念上和其它语言的 null、None、nil、NULL一样,都指代零值或空值。

make和new的区别

  • make 只用于 slice、map 、channel 的初始化,返回的还是这三个引用类型本身,因为这三种类型就是引用类型,所以就没必要返回其指针了

  • new 用于类型的内存分配,并且内存对应的值为类型零值,返回的是指向类型的指针。

  • 在 Go 语言中我们使用引用类型的变量需要先申明、分配内存空间,否则在赋值是会出错。值类型的变量除外,因为其在申明时就分配了默认的内存空间。这也是 new 和 make 的作用。make 和 new 都是用来做内存分配。