GO学习笔记——指针(9)

GO语言也有指针,本质上和C/C++没有差别,但是在用法上有很多差别,GO语言中的指针是弱化版的C/C++指针。

先来看一段简单的代码

func main() {
	a := 1
	b := &a
	fmt.Println(reflect.TypeOf(b),b,*b)
}

执行结果如下

*int 0xc04204e080 1

由此可见:

  • 这个b的类型就是int类型的指针,用*int表示
  • b指向了a,b的值就是a的地址,也就是说a的地址就是0xc04204e080
  • *b就是解引用指针,得到的是a的值,也就是1

基本的用法看起来和C++好像没有太大的变化,但是还是有几点是需要注意的。


指针的零值

C/C++中指针可以为NULL,那么在GO语言中,空指针就是nil了,这也是我们说的指针的零值(不赋值时候的值)。

GO语言中的指针不能拿来运算

GO语言中的指针是简单的,弱化版的C/C++指针,就是因为GO语言规定指针不可以进行运算,而C/C++中的指针可以进行++/--操作,也可以进行+1,+2这样的运算操作,GO语言简单就是简单在它规定了这样的操作是不合法的,编译器会自动报错。

值传递配合指针实现引用传递

在函数传参的时候,GO语言只有值传递一种方式,没有引用传递

来看下面的代码

func print(a int){
	fmt.Println(a)
}
func main() {
	a := 1
	print(a)
}

这就是典型的值传递,才调用print函数的时候,会拷贝一份变量a,作为形式参数传给print函数,调用完print函数之后,这个临时的拷贝的变量就被销毁了。这中间有一次拷贝操作,如果这个变量不是int,而是一个自定义类型,且这个类型的大小非常大。那我们如果拷贝了这个变量,肯定就会消耗一定的空间。

这个时候我们就可以使用指针来搞定,同时这也保证了,这次值传递传递的是变量的地址,而不是整个变量,起到了引用传递的效果。

func print(pa *int){
	*pa = 2    //将pa指向的地址的值改为了2
	fmt.Println(*pa)
}
func main() {
	a := 1
	fmt.Println(a)    //执行print函数之前a是1
	print(&a)
	fmt.Println(a)    //执行print函数之后a是2
}

来看下输出结果

1
2
2

a的值在调用完print函数以后发生了变化,是因为print函数体内通过指针改变了原来的值,这个C语言的实现的引用传递方式类似。

猜你喜欢

转载自blog.csdn.net/lvyibin890/article/details/83272628
今日推荐