Go的指针

Go的指针

指针变量:保存指针地址

Go语言中的指针不能进行偏移和运算

两个符号:&(取地址)和*(根据地址取值)

指针地址和指针类型

每个变量在运行时都拥有一个地址,这个地址代表变量在内存中的位置

Go语言中的值类型(int、float、bool、string、array、struct)都有对应的指针类型

取变量指针

ptr := &v    // v的类型为T
  • v:代表被取地址的变量,类型为 T
  • ptr:用于接收地址的变量,类型为*T,称为T的指针类型,*代表指针
func main() {
  a := 10
  b := &a
  fmt.Printf("a: %d, ptr: %p\n", a, &a)
  fmt.Printf("b: %p, type od b: %T\n", b, b)
  fmt.Println(&b)
}
// a: 10, ptr: 0xc000014080
// b: 0xc000014080, type od b: *int
// 0xc00000c028

指针取值

新变量对普通变量使用&操作符取地址后会获得这个普通变量的地址

新变量保存的是地址,新变量是一个指针

*新变量 可以取到新变量这个指针所指向的值

func main() {
  a := 10
  b := &a
  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

取地址操作符&和取值操作符*是一对互补操作符

&取出地址,*根据地址取出地址指向的值

变量、指针地址、指针变量、取地址、取值 :

  • 取地址(&)操作,让新变量变成指针变量
  • 指针变量的值是指针地址
  • 对指针变量进行取值(*)操作,可以获得指针变量指向的原变量的值

指针传值

func modify1(x int) {
  x := 100
}
func modify2(x *int) {
  *x = 100
}
func main() {
  a := 10
  modify1(a)
  fmt.Println(a)  // 10
  modify2(&a)
  fmt.Println(a)  // 100
}

new和make

错误事例

func main() {
  var a *int
  *a = 100
  fmt.Println(*a)
  
  var b map[string]int
  b["hello"] = 100
  fmt.Peintln(b)
}

上面的代码会引发panic

var a *int只是声明了一个指针变量a但是没有初始化

指针作为引用类型需要初始化后才会拥有内存空间,才可以给它赋值

  • Go语言中对于引用类型的变量,我们在使用的时候不仅要声明它,还要为它分配内存空间,否则我们的值就没办法存储

  • 对于值类型的声明不需要分配内存空间,是因为它们在声明的时候已经默认分配好了内存空间

  • Go语言中new和make是内建的两个函数,主要用来分配内存

new

func new(Type) *Type
  • Type表示类型,new函数只接受一个参数,这个参数是一个类型
  • *Type表示类型指针,new函数返回一个指向该类型内存地址的指针

new函数不太常用,使用new函数得到的是一个类型的指针,并且该指针对应的值为该类型的零值

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

var声明指针变量后,需要用new初始化

func main() {
  var a *int
  a = new(int)
  *a = 10
  fmt.Println(*a)
}

make

make只用于slice、map以及chan的内存创建,而且它返回的类型就是这三个类型本身

func main() {
  var b map[string]int           // 声明b是一个map变量
  b = make(map[string]int, 10)   // 初始化map变量
  b["age"] = 25                  // 赋值
  fmt.Println(b)                 // map[age:25]
}

new和make的区别

  • 都是用来分配内存的
  • make只用于slice、map以及chan的内存创建,而且它返回的类型就是这三个类型本身
  • 而new用于类型的内存分配,并且内存对应的值为类型零值,返回的是指向类型的指针
posted @ 2020-01-03 09:14  _慕  阅读(259)  评论(0编辑  收藏  举报
Title
返回顶部