Golang的指针

很多主流语言中都有指针作为变量的一种,go也不例外。一方面,go保留了例如c、cpp等语言的严谨性,同时兼有python、函数式编程语言的灵活性;针对长历史的语言,去其糟粕取其精华,依然保留了指针。

值传递和引用传递

相信在初学c语言时,指针对于大部分人来说有些难以理解,尤其是不了解计算机底层的人,传值、传地址难以区分。c和cpp中,指针操作有传值和**传引用(地址)**两种方式。

  • 传值

传值就是传递变量的值,相当于把这个变量复制一份,用于函数域中的操作。函数域之外,变量的值不受影响。

  • 传引用

传引用,也叫传地址,在某个函数中操作以引用方式传进去的变量,会改变变量实际的值,也就是在函数域之外,变量的值也会被改变。

void con_value(int num){
    num++;
}

void con_refer(int &a){
    num++;
}

int main(){
    int num = 1;
    con_value(num);
    printf("n1 = %d\n", num);
    
    con_refer(num);
    printf("n2 = %d\n", num);
}

con_value()就是值传递,con_refer()就是传引用。执行main()函数后,n1 = 1因为传入的只是值,相当于con_value()num复制了一份用来操作,实际上函数的作用域之外num没有变;n2 = 2con_refer()则是传入的引用,直接使用了num,所以无论函数内还是外,num的值都发生的改变。

go中的指针

在go语言中,指针只有值传递这一种,也就是函数做的只是拷贝,然后再使用。

情况一:函数内改变不影响函数外

var a int
fun f(a int){
    ...
}

这种情况下,f()中对a的改变不会影响的外面的a,因为是拷贝过去的。

情况二:通过指针改变变量实际的值(通过传递指针达到引用传递的效果)

var na int = 2
var pa *int = &na

func f(pa *int) {
	*pa++
	fmt.Println(*pa)
}

首先,naint型变量,而pa是指向na地址的指针,我们通过传入一个指针来改变变量的值。同样以值传递的思想,函数f()拷贝了一份pa,但是无论怎么拷贝,拷贝出的东西它都是指向na的地址的,所以通过传一个指针就可以改变对应地址的值,函数外na的值也发生了改变。

情况三: 关于object的传递

var object Object

func f(object Object){
    ···
}

如果是这种情况,就要看在定义object时,是把他当作值传递来用还是引用传递来用。

// 1.这种情况可以安全的当作值传递来用
type Object struct {
	a *int
}

func f(object Object){
    ...
}

func main(){
	l := 9
	o := Object{&l} // 不管怎么拷贝,拷贝出的 object.a 都是指向原本l的地址,会改变l的值
	f(o)	
}


// 2.如果对象需要例如维护某些状态,仅仅传值是不会改变函数外参数原本的值的,如:st
type Object struct {
	a *int
	st bool // 一个bool值
}
func fo(object Object) { // 传值,一个Object类型的值
	*object.a ++
	object.st = false  // 原本的st不会被改变
}

func main() {
	l := 9
    o := Object{&l, true}
	fo(o)
	fmt.Printf("%d  ", *o.a) // 10
	fmt.Println(o.st)	// true
}

// 3.如果需要,传指针来实现引用传递的效果,如下面的 st 被修改了
func p_fo(object *Object) {	// 接收一个Object类型的指针
	*object.a++
	object.st = false	// 拷贝后的 object 指向原来的地址,赋值操作实际上改变原值
}

func main() {
	l := 9
	o := Object{&l, true}
	o_p := &o
	p_fo(o_p)
	fmt.Printf("%d  ", *o.a) // 10
	fmt.Println(o.st) // false
}

所以,在定义一个Object时,要考虑以后是用值还是用引用,再来定义使其更方便的被使用。

Licensed under CC BY-NC-SA 4.0
自认为是幻象波普星的来客
Built with Hugo
主题 StackJimmy 设计