速戰速決 go - go 基礎: 指針

速戰速決 go https://github.com/webabcd/GoSample
作者 webabcd

速戰速決 go - go 基礎: 指針

示例如下:

basic/pointer.go

// go 基礎 - 指針

package basic

import (
	"fmt"
)

func PointerSample() {
	pointer_sample1()
	pointer_sample2()
	pointer_sample3()
	pointer_sample4()
}

func pointer_sample1() {
	// 作爲數據類型時 * 表示指針,比如 *int 就是指向 int 的指針
	// 作爲運算符時 * 表示取指針指向的值
	// 運算符 & 表示取值的指針

	var a int = 1   // 爲變量 a 賦值 1
	var b *int = &a // 取變量 a 的地址,並賦值給變量 b(變量 b 保存的是一個地址,即變量 b 是一個指針)
	var c int = *b  // 取指針 b 指向的值,並賦值給變量 c

	// b 指向的值是 a
	// a 和 c 的值是相同的,但是他們的指針是不同的
	fmt.Printf("%d, %d, %d\n", a, *b, c)  // 1, 1, 1
	fmt.Printf("%p, %p, %p\n", &a, b, &c) // 0xc000128058, 0xc000128058, 0xc00012807
	fmt.Printf("%T, %T, %T\n", a, b, c)   // int, *int, int

	// 注:雖然切片是一個指針,但是不能對其做取值操作,否則會編譯時報錯 invalid operation: cannot indirect d (variable of type []int)
	// d := []int{1, 2, 3, 4, 5}
	// fmt.Println(*d)
}

func pointer_sample2() {
	// 聲明一個指針,其默認值爲 nil
	var a *int
	fmt.Printf("%p\n", a) // 0x0
	// nil 的地址是 0x0,所以像下面這樣賦值是不可以的,因爲無法對地址 0x0 取值
	// *a = 100

	// 可以通過 new() 的方式聲明一個指向指定類型的指針,其會自動用默認值初始化
	b := new(int)
	fmt.Printf("%d, %p\n", *b, b) // 0, 0xc000186060
	*b = 1
	fmt.Printf("%d, %p\n", *b, b) // 1, 0xc000186060
}

func pointer_sample3() {
	a := &struct {
		a int
	}{}

	// 雖然 a 是指針,需要這麼 (*a).a = 123 使用,但是 go 是支持語法糖(syntactic sugar)技術的,他會自動轉換的,所以你可以這麼 a.a = 456 使用
	(*a).a = 123
	a.a = 456
	fmt.Println(a) // &{456}
}

// 本例用於演示指針的指針
// 指針會指向一個值,也就是說這個值的地址就是這個指針,而保存這個地址的變量的地址,就是指針的指針
func pointer_sample4() {
	a := 0   // 變量 a
	b := &a  // 變量 a 的指針
	c := &b  // 變量 b 的指針,即變量 a 的指針的指針(注意:寫成 &&a 是肯定不行的,不可能有這種運算符)
	d := *b  // 對變量 b 取值,返回變量 a 的值
	e := *c  // 對變量 c 取值,返回變量 a 的指針
	f := **c // 對變量 c 取值再取值,返回變量 a 的值

	fmt.Printf("%v, %v, %v, %v, %v, %v\n", a, b, c, d, e, f) // 0, 0xc0000140e8, 0xc000006030, 0, 0xc0000140e8, 0

	// 聲明一個指針的指針
	var g **int
	// 上面說過了,像下面這樣賦值是不允許的,因爲指針的默認值是 nil,而 nil 的地址是 0x0,無法對 0x0 取值
	// **g = 100
	g = c
	fmt.Printf("%v, %v, %v\n", g, *g, **g) // 0xc000006030, 0xc0000140e8, 0

	h := 0
	i := &h
	j := &i
	k := &i
	// j 值和 k 值是一樣的,它們都是 i 的指針,即 h 的指針的指針
	//
	fmt.Printf("%p, %p, %p, %p\n", j, k, &j, &k) // 0xc000006038, 0xc000006038, 0xc000006040, 0xc000006048
}

速戰速決 go https://github.com/webabcd/GoSample
作者 webabcd

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章