Go语言基础之指针!

指针是一个地址,指针类型是依托于某一个类型而存在的。

Go 里面的基本数据类型 intfloat64string

  • 它们所对应的指针类型为 *int*float64*string等。

指针的定义:

  • 语法格式:var 指针变量名 *数据类型 = &变量
  • & 为取地址符号,通过 & 符号获取某个变量的地址,然后赋值给指针变量。
1
2
3
4
5
6
7
8
9
10
import (
"fmt"
)

func main() {
var num int = 666
var numPtr *int = &num
fmt.Println(numPtr) // num 变量的地址值 0xc00001c098
fmt.Println(&numPtr) // 指针变量本身的地址值 0xc00000a028
}

img

npmPtr 指针变量指向变量 num0xc00001c098num 变量的地址

  • 0xc00000a028 为指针变量本身的地址值。

使用 new(T) 函数创建指针变量:

  • new(T) 函数为每个类型分配一片内存
    • 内存单元保存的是对应类型的零值,函数返回一个指针类型。
1
2
3
4
5
6
7
8
9
import (
"fmt"
)

func main() {
numPtr := new(int)
fmt.Println(numPtr) // 0xc000122058
fmt.Println(*numPtr) // 0
}

错误的类型地址赋值:

  • 当指针所依托的类型与变量的类型不一致时,Go 编译器会报错,类型不匹配。
1
2
3
4
func main() {
var num float64 = 666
var numPtr *int = &num // cannot use &num (value of type *float64) as type *int in variable declaration
}

获取和修改指针所指向变量的值

  • 通过指针获取所指向变量的值
  • 对指针使用 * 操作符可以获取所指向变量的值。
1
2
3
4
5
6
7
func main() {
var num int = 666
var numPtr *int = &num

// 获取 num 的值
fmt.Println(*numPtr) // 666
}

通过指针修改所指向变量的值

  • 同时也可以对指针使用 * 操作符修改所指向变量的值。
1
2
3
4
5
6
7
8
9
10
11
12
import (
"fmt"
)

func main() {
var num int = 666
var numPtr *int = &num

// 修改 num 的值
*numPtr = 555
fmt.Println(num) // 555
}

值类型和引用类型

值类型:

  • 基本数据类型int系列,float系列,bool,string,数组和结构体 struct

引用类型:

  • 指针,slice切片,map,管道chan,interface等都是引用数据类型

值类型:

  • 变量直接存储值,内存通常在栈中分配

img

引用类型:

变量存储的是一个地址,这个地址对于的空间才是真正的存储数据(值)

  • 内存通常在堆上分配,当没有任何变量引用这个地址时
  • 改地址对应的数据空间就成为了一个垃圾,由GC来回收

img

内存的栈区和堆区:

img