Go语法学习笔记(四) | 青训营笔记

83 阅读2分钟

这是我参与「第五届青训营」伴学笔记创作活动的第5天。

这是Go语法笔记系列的第四篇,在这篇笔记中,我将总结和整理Go语言中范围和指针的基本概念和用法。

范围(Range)

在Go语言中,可以用range关键字配合for语句来实现对可迭代数据(例如切片slice、数组array、通道channel、集合map等)的遍历访问。range向外提供两个数据,代表keyvalue,在数组中表现为下标和数据,下面是一些例子:

nums := []int{2, 3, 4}
sum := 0
for i, num := range nums {
	sum += num
	if num == 2 {
		fmt.Println("index:", i, "num:", num) // index: 0 num: 2
	}
}

上面的例子里,使用range nums创建了一个nums切片的range,它将在循环中迭代,每次迭代会向外给出两个值,即上面的inum。在上面的例子里,i在整个循环过程中的值依次为0, 1, 2num在整个循环过程中的值为2, 3, 4,即nums[0], nums[1], nums[2]

如果不需要用到key或者value的值,则可以简单地使用_代替,以忽略它们。例如for _, num := range nums或者for i, _ := range nums。此外,如果要忽略的是value的值,也可以直接写成for i := range nums,这与for i, _ := range nums是等价的。

map的遍历中使用range的例子如下所示:

m := map[string]string{"a": "A", "b": "B"}
for k, v := range m {
	fmt.Println(k, v) // b 8; a A
}
for k := range m {
	fmt.Println("key", k) // key a; key b
}

指针(Pointer)

不同于Java等语言,Go语言中的参数传递、赋值等操作一律是值传递,而非引用传递,更准确地说,Go语言中并没有引用这一概念。与C语言类似,Go语言没有引用机制,只提供指针。Go语言的指针使用的相关语法也与C语言很相近,指针的类型为*type,获取一个变量的指针的方法是使用&,获取一个指针指向的变量的方法是使用*。比如对于变量var a int,要获取指向它的指针,可以使用&a(即取得a的内存地址);对于指针变量var b *int,要获取它指向的变量,可以使用*b。下面是一个例子:

func add2(n int) {
	n += 2
}

func add2ptr(n *int) {
	*n += 2
}

func main() {
	n := 5
	add2(n)
	fmt.Println(n) // 5
	add2ptr(&n)
	fmt.Println(n) // 7
}

通过上面的例子要说明的是,Go语言的函数传参是值传递,函数对参数值的修改并不会影响到函数外的变量的值,需要使用指针才能实现函数内对函数外变量的修改。另外,Go语言中存在的概念,它的关键字是nil,每一个未初始化的指针的值就是nil,即空指针。