什么时候使用指针?

Lisanaaa · · 5640 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

大家好,我是离散。🌞

今天给大家分享一下什么时候适合使用指针。

image

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+订阅;
  • 穿越火线排位第一赛季江西赛区第七名,很久没玩,欢迎找我约游戏。*

有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:Lisanaaa

查看原文:什么时候使用指针?

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

5640 次点击  ∙  1 赞  
加入收藏 微博
2 回复  |  直到 2021-03-15 14:20:30
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传