什么是指针

咱们都晓得,程序运行时的数据是寄存在内存中的,每一个存储在内存中的数据都有一个编号,这个编号就是内存地址。咱们能够依据这个内存地址来找到内存中存储的数据,而内存地址能够被赋值给一个指针。咱们也能够简略的了解为指针就是内存地址。

指针的申明和定义

在Go语言中,获取一个指针,间接应用取地址符&就能够。
示例:

func main() {  name := "微客鸟窝"  nameP := &name //取地址  fmt.Println("name变量值为:", name)  fmt.Println("name变量的内存地址为:", nameP)}//运行后果://name变量值为: 微客鸟窝//name变量的内存地址为: 0xc00004e240
  • nameP 指针的类型是 *string
  • Go语言中,*类型名示意一个对应的指针类型
变量内存中数据内存地址
name := "微客鸟窝"微客鸟窝0xc00004e240
nameP := &name0xc00004e2400xc00004e360

从下面表格能够看到:

  1. 一般变量 name 的值是微客鸟窝,寄存在内存地址为 0xc00004e240 的内存中
  2. 指针变量 namep 的值是一般变量的内存地址 0xc00004e240
  3. 指针变量 nameP 的值寄存在 内存地址为 0xc00004e360 的内存中
  4. 一般变量存的是数据,指针变量存的是数据的地址

var 关键字申明

咱们也能够应用 var 关键字申明

var nameP *stringnameP = &name

new 函数申明

nameP := new(string)nameP = &name

能够传递类型给这个内置的 new 函数,它会返回对应的指针类型。

指针的操作

这里强调一下:
指针变量是一个变量,这个变量的值是指针(内存地址)!
指针变量是一个变量,这个变量的值是指针(内存地址)!
指针变量是一个变量,这个变量的值是指针(内存地址)!

  1. 获取指针指向的值:
    只须要在指针变量钱加 * 号即可取得指针变量值所对应的数据:

    nameV := *namePfmt.Println("nameP指针指向的值为:",nameV) //nameP指针指向的值为: 微客鸟窝
  2. 批改指针指向的值:

    *nameP = "公众号:微客鸟窝" //批改指针指向的值fmt.Println("nameP指针指向的值为:",*nameP)fmt.Println("name变量的值为:",name)//运行后果://nameP指针指向的值为: 公众号:微客鸟窝//name变量的值为: 公众号:微客鸟窝
  3. 咱们发现nameP 指针指向的值被扭转了,变量 name 的值也被扭转了
  4. 因为变量 name 存储数据的内存就是指针 nameP 指向的内存,这块内存被 nameP 批改后,变量 name 的值也被批改了。
  5. 通过 var 关键字间接定义的指针变量是不能进行赋值操作的,因为它的值为 nil,也就是还没有指向的内存地址

    //谬误示例var intP *int*intP = 10  //谬误,应该先给调配一块内存,内存地址作为变量 intP 的值,这个内存就能够寄存 10 了。//应该应用var intP *int  //申明int类型的指针变量 intPintP = new(int) // 给指针调配一块内存*intP = 66 fmt.Println(":::",intP)  //::: 0xc0000ac088fmt.Println(*intP) //66//简短写法var intP := new(int)*intP=66

指针参数

当给一个函数应用指针作为参数的时候,就能够在函数中,通过形参扭转实参的值:

func main() {    name := "无尘"    modify(&name)    fmt.Println("name的值为:",name)}func modify(name *string)  {    *name = "wucs"}//运行后果://name的值为: wucs

指针接收者

  1. 如果接收者类型是 map、slice、channel 这类援用类型,不应用指针;
  2. 如果须要批改接收者,那么须要应用指针;
  3. 如果接收者是比拟大的类型,能够思考应用指针,因为内存拷贝便宜,所以效率高。

什么状况下应用指针

  • 不要对 map、slice、channel 这类援用类型应用指针;
  • 如果须要批改办法接收者外部的数据或者状态时,须要应用指针;
  • 如果须要批改参数的值或者外部数据时,也须要应用指针类型的参数;
  • 如果是比拟大的构造体,每次参数传递或者调用办法都要内存拷贝,内存占用多,这时候能够思考应用指针;
  • 像 int、bool 这样的小数据类型没必要应用指针;
  • 如果须要并发平安,则尽可能地不要应用指针,应用指针肯定要保障并发平安;
  • 指针最好不要嵌套,也就是不要应用一个指向指针的指针,尽管 Go 语言容许这么做,然而这会使你的代码变得异样简单。