指针的使用

  在Go语言中,指针可以说无处不在,它既是重点也是难点,想掌握Go语言开发学会使用指针是一道永远无法避开的坎。
 
  先来看一段错误代码:

package main

import "fmt"

func main() {
   var pointer *int
   fmt.Printf("变量pointer的数据类型为%T,值为%+v \n", pointer, pointer) // 变量pointer的数据类型为*int,值为<nil>

   // 由于变量pointer还是空指针,此时通过指针修改值就会抛出panic
   *pointer = 1024 // panic: runtime error: invalid memory address or nil pointer dereference

   fmt.Printf("*pointer = %+v \n", *pointer) // 这里不会执行,因为上面抛出了panic
}

  再来看正确的使用方式:

package main

import "fmt"

func main() {
   pointer := new(int)
   fmt.Printf("变量pointer的数据类型为%T,值为%+v \n", pointer, pointer) // 变量pointer的数据类型为*int,值为0xc00001a090

   *pointer = 1024

   fmt.Printf("*pointer = %+v \n", *pointer) // *pointer = 1024
}

  使用“&”符号获取变量的内存地址:

package main

import "fmt"

func main() {
   var pointer *int
   var num int

   pointer = &num  // 把变量num的内存地址保存到变量pointer,也可以理解为pointer指向了num
   *pointer = 9527 // 通过指针修改变量num的值

   fmt.Printf("pointer = %v \n", pointer)   // pointer = 0xc00001a090
   fmt.Printf("*pointer = %v \n", *pointer) // *pointer = 9527
   fmt.Printf("num = %v \n", num)           // num = 9527
   fmt.Printf("&num = %v \n", &num)         // &num = 0xc00001a090

   // 保存指针的指针变量本身也需要使用内存保存,故指针变量本身也有指针(俗称套娃)
   fmt.Printf("&pointer = %v \n", &pointer) // &pointer = 0xc000012028
}

  结构体指针变量的使用:

package main

import "fmt"

// Human 定义一个名为Human的结构体
type Human struct {
   name   string // 姓名
   age    int    // 年龄
   gender string // 性别
}

func main() {
   // 定义结构体指针变量hum
   hum := &Human{} // 等价于 var hum *Human = &Human{}

   // 标准写法和语法糖写法的比较
   (*hum).name = "张三" // 标准写法(变量名前加*符号)【推荐】
   hum.age = 18       // 语法糖写法【不推荐】

   (*hum).gender = "男"

   fmt.Printf("俺叫%v%v),今年%v岁。\n", hum.name, hum.gender, hum.age)
   // 俺叫张三(男),今年18岁。
}

//========== 总结 ==========//
// 1、使用结构体指针变量时应使用标准写法(即变量名前加*符号),避免使用语法糖写法,这样能提高代码可读性,开发者看到变
//    量名前的*符号就知道该变量是指针变量,而不需要跳转到变量定义语句才能知道是结构体变量还是结构体指针变量。

Copyright © 2024 码农人生. All Rights Reserved