为了账号安全,请及时绑定邮箱和手机立即绑定

在设计和编写库时,什么时候应该使用指针作为参数,什么时候不应该?

在设计和编写库时,什么时候应该使用指针作为参数,什么时候不应该?

Go
陪伴而非守候 2021-12-07 16:02:00
对不起,如果我的问题看起来很愚蠢。我的背景是 PHP、Ruby、Python、Lua 和类似语言,我对现实生活中的指针没有理解。从我在 Internet 上阅读的内容以及我在提出的问题(何时是指针惯用语?)中得到的答复中,我了解到:复制大数据时应该使用指针。不是获取整个对象层次结构,而是接收它的地址并访问它。当您在结构上有一个修改它的函数时,必须使用指针。所以,指针似乎是一件很棒的事情:我应该总是将它们作为函数参数获取,因为它们非常轻量级,如果我以某种方式最终不需要修改结构上的任何内容也没关系。但是,凭直觉看这句话,我能感觉到它听起来很毛骨悚然,但我不知道为什么。那么,作为正在设计结构及其相关函数或只是函数的人,我应该什么时候接收指针?我什么时候应该收到一个值,为什么?换句话说,我的NewAuthor方法&Author{ ... }什么时候应该返回,Author{ ... }什么时候应该返回?我的函数什么时候应该获取一个指向作者的指针作为参数,什么时候它应该只获取 type 的值(副本)Author?
查看完整描述

2 回答

?
凤凰求蛊

TA贡献1825条经验 获得超4个赞

指针和值都需要权衡。


一般来说,指针会指向系统中的其他一些内存区域。无论是想要将指针传递给局部变量的函数的堆栈还是堆上的某个位置。


func A() {

    i := 25

    B(&i) // A sets up stack frame to call B,

          // it copies the address of i so B can look it up later.

    // At this point, i is equal to 30

}

func B(i *int){

     // Here, i points to A's stack frame.

     // For this to execute, I look at my variable "i", 

     //   see the memory address it points to, then look at that to get the value of 25.

     // That address may be on another page of memory, 

     // causing me to have to look it up from main memory (which is slow).

     println(10 + (*i)) 


     // Since I have the address to A's local variable, I can modify it.

     *i = 30

}

每当我要查看它指向的数据时,指针都要求我不断地取消引用它们。有时你不在乎。其他时候它很重要。这真的取决于应用程序。


如果该指针必须被多次取消引用(即:您传入一个数字以在一堆不同的计算中使用),那么您将继续支付成本。


与使用值相比:


func A() {

    i := 25

    B(i) // A sets up the stack frame to call B, copying in the value 25

    // i is still 25, because A gave B a copy of the value, and not the address.

}

func B(i int){

     // Here, i is simply on the stack.  I don't have to do anything to use it.

     println(10 + i) 


     // Since i here is a value on B's stack, modifications are not visible outside B's scpe

     i = 30

}

由于没有什么可以解引用,所以基本上可以自由使用局部变量。


如果这些值很大,则会发生传递值的不利方面,因为将数据复制到堆栈不是免费的。


对于 int 来说,这是一个清洗,因为指针是“int”大小的。对于结构或数组,您正在复制所有数据。


此外,堆栈上的大对象可以使堆栈变得特别大。Go 通过堆栈重新分配很好地处理了这个问题,但在高性能场景中,它可能对性能的影响太大。


还有一个数据安全方面(不能修改我通过值传递的东西),但我不认为这在大多数代码库中通常是一个问题。


基本上,如果您的问题已经可以通过 ruby、python 或其他没有值类型的语言解决,那么这些性能上的细微差别并不重要。


一般来说,在学习语言时,将结构作为指针传递通常会做“正确的事情”。


对于所有其他类型或您希望保持为只读的内容,请传递值。


该规则也有例外,但最好是在需求出现时学习这些规则,而不是试图一次性重新定义您的世界。如果这是有道理的。


查看完整回答
反对 回复 2021-12-07
?
慕姐8265434

TA贡献1813条经验 获得超2个赞

只需您可以在任何您想要的地方使用指针,有时您不想更改您的数据。它可能代表抽象数据,您不想显式复制数据。只需按值传递,让编译器完成它的工作。


查看完整回答
反对 回复 2021-12-07
  • 2 回答
  • 0 关注
  • 136 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信