Skip to content

指针

学过 C 语言中的指针, 就可以理解为 Go 语言的指针, Go 语言中的指针是比较克制的

  1. 指针是一种存放内存地址的数据类型
  2. 指针总是会指向一块特定的内存空间
  3. 指针在go语言中不能直接参与运算(需要使用 unsafe 包中的方法)

指针变量

go
package main

import "fmt"

func main() {
	num := 1         // 普通变量, 保存的是具体的数据
	fmt.Println(num) // 10

	numPtr := &num       // 指针变量, 保存的是内存地址
	fmt.Println(numPtr)  // 0xc0000120c0
	fmt.Println(*numPtr) // 解引用:通过内存地址获取这个空间中保存的数据内容
}

取地址符 与 解引用符

  • 取地址符: &
  • 解引用符: *

悬垂指针

也叫做: 野指针 空指针

它表示, 声明了指针变量, 但是没有指向任何内存地址, 这种指针变量是没有意义的

go
package main

import "fmt"

func main() {
	var x *int

	// 这个 nil 相当于 C 语言中的 NULL
	fmt.Println(x)  // <nil>
	fmt.Println(*x) // 0x00
}

指针初始化

  • 推荐使用内置方法: new
  • 如果变量已经存在可以使用取地址符: &varName
go
package main

import "fmt"

func main() {
	// 注意:
	// 1.new 方法的返回值是一个指针类型的值(内存地址)
	// 2.由于需要返回一个指针,所以传入的是类型(需要根据类型计算需要多少内存空间)而不是具体的值
	intPtr := new(int) // 初始化指针变量
	*intPtr = 10       // 解引用赋值
	fmt.Println(*intPtr)

	num := 20
	numPtr := &num
	fmt.Println(*numPtr)
}

nil 详解

  1. nil 代表的是 Go 语言中的空值(或者叫零值)

  2. nil 是标识符, 不是一种数据类型(用于表示指针变量没有指向具体内存地址的状态)

  3. Go 语言中的不同数据类型的零值(可以简单的理解为默认值)

    1. bool: false
    2. int/uint等数字类型: 0
    3. string: ""
    4. array(如: [3]int): []
    5. struct 没有零值, 但内部的字段有零值
    6. pointer/slice/map/channel/func/interface: nil
  4. 3 可以知:只有数据存在堆区的数据类型的默认值是 nil, 这样证明了 2

go
package main

import "fmt"

func main() {
	// 这样是不行的, 数组的数据存在栈区
	// var nums [3]int = nil
	// fmt.Println(nums)

	// 这样是可以的, 切片的数据存在堆区
	var nums []int = nil
	fmt.Println(nums)
}

堆内存 & 栈内存

Go 是站在 C 这个巨人的肩膀上创造出来的, 但是其底层 的处理还是离不开C中的一些概念(比如: 堆内存 栈内存)

  • 栈内存: 随函数调用创建, 函数返回时自动销毁
  • 堆内存: 手动分配, 需要显式释放(或由垃圾回收器管理)

这一点在C 语言中比较明显, 在 Go 语言中反而不太明显, Go 为了 更简单(不需要手动管理内存), 就需要垃圾回收器, 但是偏偏它又支持直接操作内存地址, 但这也就导致了, 内存操 作不透明, 都是黑魔法, 内存相关操作, 理解起来比 C 还费劲

Released under the MIT License.