大家好,我是离散。🌞
今天给大家分享一下什么时候适合使用指针。
image copied from https://commons.wikimedia.org/wiki/File:Golang.png
指针是什么
我们经常会听到别人说Golang是值传递,某某某是引用传递,某某某是指针传递,等等各种各样的说法。
那么首先他们的区别是什么呢?什么是指针?指针其实也是一个变量,只不过这个变量里面存的不是int,float,struct,而是一个地址address,然后在这个address上所存储的数据可以通过指针来被阅读到。
OK,指针变量存储的是一个地址,地址从哪里来的?那就得问一个变量的地址怎么取得呢?在变量前面加上一个&符号就行。
好的,指针变量存储了这个地址了,那这个地址所存储的值怎么被阅读到呢?也就是指针所指向的值怎么拿到呢?在指针变量前面加上一个*符号就行。
怎么修改指针所指向的数据呢?在前面加上*符号之后再赋一个新的值就可以了。
func main() {
a := "Lisanaaa"
b := &a
fmt.Println("The value of a is:", a)
fmt.Println("The address of a is:", &a)
fmt.Println("The value of b is:", b)
fmt.Println("Before, the value b points to is:", *b)
*b = "not Lisanaaa"
fmt.Println("After, the value b points to is:", *b)
}
输出是:
The value of a is: Lisanaaa
The address of a is: 0xc00000e1e0
The value of b is: 0xc00000e1e0
Before, the value b points to is: Lisanaaa
After, the value b points to is: not Lisanaaa
指针的作用
为什么要有指针这个东西?它有什么关键性的作用呢?我们来看下面这段代码:
type Lisanaaa struct {
Description string
}
func main() {
a := Lisanaaa{
Description: "niubi",
}
fmt.Println("Before, the description of Lisanaaa is:", a.Description)
modify(a)
fmt.Println("After, the description of Lisanaaa is:", a.Description)
}
func modify(a Lisanaaa) {
a.Description = "laji"
}
输出是
Before, the description of Lisanaaa is: niubi
After, the description of Lisanaaa is: niubi
为什么我明明改了a的description,但是descriptipn却没有变化呢?
因为在我们传入参数的时候,这个a是做了一份拷贝的,也就是说现在存在两个a,一个是main函数的a,另一个是modify函数的a,modify函数改变自己的a并不会影响到main函数里面的a。
那怎么样才能让我们的modify函数内部可以改变main函数的变量呢?我们可以通过传入指针的形式。
type Lisanaaa struct {
Description string
}
func main() {
a := Lisanaaa{
Description: "niubi",
}
fmt.Println("Before, the description of Lisanaaa is:", a.Description)
modify(&a)
fmt.Println("After, the description of Lisanaaa is:", a.Description)
}
func modify(a *Lisanaaa) {
a.Description = "laji"
}
输出是:
Before, the description of Lisanaaa is: niubi
After, the description of Lisanaaa is: laji
这也告诉我们一个道理,只有我们自己才可以骂自己laji,其他人改变不了我们。Please be yourself! Always on the way!
看到上面的结果,我们不禁又问自己一个问题,传指针是不是就不拷贝了?错,还是要拷贝的,只不过我们现在拷贝的就是这个指针变量而已,不用像刚才那样整个a都拷贝一份了。
所以指针的作用:
1. 指针不但可以帮助函数内部修改外部变量的值,还可以帮助我们在任何地方修改其所指向数据的值;
2. 传递指针参数可以节省拷贝大结构体的内存开销;
什么时候适合用指针
如果需要修改外部变量的值,我们需要使用指针;
不需要对map,slice等引用类型使用指针,因为他们本身就是一个指针,这个我下一篇再分享;
如果有超级大的结构体需要作为函数的参数,使用指针可以节省内存开销;
因为指针可以修改其指向数据的值,所以最好不要随意在并发场景下使用;
最好不要嵌套使用指针,比如b := &a, c := &b,这样代码会比较复杂难懂。
总结
指针也是变量,只不过存储的是地址;
通过指针可以去修改其指向数据的值。
指针可以帮助我们在任何地方修改其所指向数据的值;
传递指针参数可以节省拷贝大结构体的内存开销;
什么时候适合用指针,详见上方版块。
希望读者们都能从这篇文章中学习到一些东西,愿我和我的homie同富有。
喜欢我的话,可以关注我的公众号:码农学习吧
作者简介:
*Lisanaaa,一名互联网从业者,热爱算法和系统设计,喜欢打篮球和健身。
- 看过2k+份简历,给超过100人提供过简历咨询,帮助他们成功拿到大厂面试;
- 曾经主导Github开源算法项目,拥有1w+ star;
- 写过自己的算法专栏,拥有超过2k+订阅;
- 穿越火线排位第一赛季江西赛区第七名,很久没玩,欢迎找我约游戏。*