← 返回文章列表

golang学习记录(10)

Go 基础学习系列第 10 篇,记录语法、示例与学习过程。

指针

指针是一个变量,其值为另一个变量的地址,即,内存地址。

指针类型的数据大小为固定值,32位系统为4字节,64位系统为8字节。

1、指针的定义和使用

取址符号:&

指针:*

传过去一个地址,通过指针进行接收

定义一个指针:

var a int = 10
var p *int = &a
// 定义了一个指针,p的类型为*int,p指向a的地址

//通过指针修改值
*p = 20
fmt.Println(a) //20

不同于C/C++语言中的指针,go语言中的指针限制了指针的运算,不能通过修改指针运算的方式访问其他内存的值

但是go语言在unsafe包中提供了一些方法,可以通过指针运算的方式访问其他内存的值,但是这种方式是不安全的,不建议使用。

2、指针的初始化

指针未初始化时,默认值为nil

在定义指针时需要进行初始化

下面是几种指针初始化写法,按需要选择,不是全部贴进同一个作用域:

var a int = 10

var p *int = &a

var p2 = new(int) //new函数返回一个指针,指向一个新的int类型的值,值为0

// 如果是结构体还能用下面的方式
p := &Person{}

取已有变量地址可以用 &,需要新零值对象时可以用 new;也可以用 &Person{} 这样的写法。

map、slice、channel的初始化最好使用make方式

需要解引用时,指针必须指向有效对象。nil map 可以读取,但写入前必须初始化。

3、swap与指针

func swap(a, b *int) {
	t := *a
	*a = *b
	*b = t
}

func main() {
	var a int = 10
	var b int = 20
	swap(&a, &b)
	fmt.Println(a, b) //20 10
}

4、Go 中的 nil

nil 是指针、切片、map、channel、函数和接口等类型可以具有的零值。它不是所有类型的统一零值:整数是 0,布尔值是 false,结构体的零值则是每个字段各自的零值。

这里有两点容易记错:nil slice 可以 append;nil map 可以读,但不能直接写。

package main

import "fmt"

func main() {
	var nums []int
	nums = append(nums, 1)
	fmt.Println(nums) // [1]

	var counts map[string]int
	fmt.Println(counts["go"]) // 0
	// counts["go"] = 1 // nil map 写入会 panic
	counts = make(map[string]int)
	counts["go"] = 1
	fmt.Println(counts["go"]) // 1
}

空切片和 nil 切片的长度都可以是 0,但 slice == nil 的结果不同;切片也不能像两个整数那样直接互相用 == 比较。

另外,接口里装着一个有类型的 nil 指针时,接口本身可能不等于 nil。以后处理 error 返回值时也要注意这一点,不能只把 nil 理解成“任何东西都是空的”。

规则可以对照 Go 规范:append、索引表达式和零值。

关于这篇文章的日期

保留旧站原始文章标注的日期;实际开始写作的时间可能更早。

同一系列 · Go 基础学习

上一篇golang学习记录(9) ←下一篇golang学习记录(11) →