速战速决 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

posted @ 2022-02-08 14:17  webabcd  阅读(304)  评论(0编辑  收藏  举报