Go 语言中的指针

导入

首先来看下面一段代码:

https://play.studygolang.com/p/RFdfacu1P30

package main
​
import "fmt"
​
func increase(x int) {
    x += 1
    fmt.Println("x inside increase() is ", x)
}
​
func main() {
    x := 1
    increase(x)
    fmt.Println("x outside is ", x)
}

输出是:

x inside increase() is  2
x outside is  1

为什么会这样呢?

因为我们向函数increase传递的仅仅是一个值,而不是一个内存中的地址,函数无法获取到该变量内存中的地址,也就无从谈起让函数外的值发生改变。

为了改变这个值,C语言首创了“指针”的用法,Go作为与之一脉相承的语言,自然不会少了这个功能。

正题

我们对上面的程序进行一点小改动,让它变成这个样子:

https://play.studygolang.com/p/Dg9UGkEVMu3

package main
​
import "fmt"
​
func increase(x *int) {
    *x += 1
    fmt.Println("x inside increase() is ", *x)
}
​
func main() {
    x := 1
    increase(&x)
    fmt.Println("x outside is ", x)
}

注意我们做出的改动:

  1. 函数increase的参数部分从(x int)变为(x *int),强制传入的数据必须是整型指针

  2. 函数体内x += 1变为*x += 1,代表让传入的指针的值自增1

  3. 传入输出语句的x变为了*x

  4. increase(x)变为了increase(&x)

这时我们再看看输出结果:

x inside increase() is  2
x outside is  2

 

我们使用*variable = x来定义一个指针,其中x为它的值。我们可以通过&操作符来获取一个指向普通变量的内存地址的指针,如上段代码所示。这两种方式是等价的。因此上段代码可以改写为:

package main
​
import "fmt"
​
func increase(x *int) {
    *x += 1
    fmt.Println("x inside increase() is ", *x)
}
​
func main() {
    *x := 1
    increase(x)
    fmt.Println("x outside is ", *x)
}

输出仍不变

 

new函数

go语言内置了一个new函数,返回一个带初始化值的指针。我们还是来对之前的代码进行更改:

https://play.studygolang.com/p/ta3BZX9hSuJ

package main
​
import "fmt"
​
func increase(x *int) {
    *x += 1
    fmt.Println("x inside increase() is ", *x)
}
​
func main() {
    x := new(int)
    increase(x)
    fmt.Println("x outside is ", *x)
}

输出:

x inside increase() is 1
x outside is 1

由此可见x指针默认被赋值为0。

 

习题

请用go语言完成下列习题:

请写出一个函数,它获取一个字符串指针,在字符串结尾添加!

提示:

func add_exclamation_mark(s *string){
    
}

下集预告

在下一期的让指针飞中,我们会继续讲解go语言,我们将会用更复杂的结构体来演示指针用法。

一个附录

文中多次出现go playground的链接,这里说明一下怎么使用go playground

点击文中的任意链接,在playground的导航栏内找到Run按钮,运行代码就可以查看效果了。在Go playground中你还可以随意对代码进行更改并运行,自己尝试go的用法。

This post belongs to Column 「让指针飞」 .

0 comments
latest

No comments yet.