当前位置: 首页 > 面试题库 >

Go中可以使用哪些指针?

阎裕
2023-03-14
问题内容

我想我了解什么是指针,但我不太了解何时使用它。
下面的摘录来自“ A Tour of Go”。
“ * Vertex”和“&Vertex”的目的是什么?
我用“顶点”替换了它们,并且运行良好。

package main

import (
    "fmt"
    "math"
)

type Vertex struct {
    X, Y float64
}

func (v *Vertex) Abs() float64 {
    return math.Sqrt(v.X*v.X + v.Y*v.Y)
}

func main() {
    v := &Vertex{3, 4}
    fmt.Println(v.Abs())
}

问题答案:

这不是指针/值区分的特别好例子,因为在这种情况下它们是可互换的!当您需要(从另一个函数)“远程”更改数据时,指针很有用。

func (v Vertex) SetX(x int) {
    v.X = x
}

func main() {
    v := Vertex{3, 4}
    fmt.Println(v)
    v.SetX(1)
    fmt.Println(v)
}

正如您将注意到的那样,这不会改变任何东西(严格来说,它会更改顶点的副本,但这在大多数情况下只是语义)!的值v仍然是{3,4}。尝试使用:

func (v *Vertex) SetX(x int) {
    v.X = x
}

func main() {
    v := &Vertex{3, 4}
    fmt.Println(v)
    v.SetX(1)
    fmt.Println(v)
}

突然,它起作用了,第二次打印了{1,4}。现在,如果您感到好奇,可以决定尝试并更改v := &Vertex{3, 4}v := Vertex{3, 4}。实际上,以上代码段仍然有效。奇怪。同样,如果您在第二个片段中将同一行更改为包含指针,则其工作方式也相同。

为什么?Go具有“透明”指针。在其他具有显式指针值的语言(例如C或C )中,您必须显式使用运算符 &*取消引用指针。C和C

甚至具有用于在字段访问和方法调用上追逐指针的特殊语法v->SetX

无论好坏,Go都会对您隐藏。如果您有一个值并需要调用一个指针方法,Go会很乐意(&v).Method()为您服务,如果您需要取消引用以调用一个值方法,它将很乐意(*v).Method()自动执行。在大多数情况下都是如此,在某些情况下(例如地图)这种情况并不适用,但总的来说仍然成立。

那么,归根结底,什么时候应该在方法上使用指针接收器呢?答案确实是“大多数时候”。在围棋风格指南通常建议使用指针类型的方法接收器除了当接收器是一个直接的别名mapfunc或者chan,它是不需要reslicing片,或者你正在做小的,一成不变的数据类型的优化(因为指针追赶比复制慢一点)。我要补充一点,您通常不应该使用直接指向指针的指针。

通常,当您不知道使用哪个时,请使用指针接收器。99%的时间使用指针会给您预期的行为,特别是如果您习惯使用Python或C#之类的语言时。比较不正确地使用指针会导致bug的情况相对比较少,因为您的Setter方法实际上没有设置任何东西,因此与得到bug的可能性进行了比较。



 类似资料:
  • 问题内容: 我有一个包装两栏式布局的古老问题。我的侧边栏处于浮动状态,因此我的容器无法包装内容和侧边栏。 似乎有许多方法可以解决Firefox中的明显错误: 在我的情况下,似乎唯一可以正常工作的解决方案是解决方案,这有点麻烦。给我带来讨厌的滚动条,并且肯定有副作用。另外,由于它的不正确行为,IE7显然不应该遭受此问题的困扰,但就我而言,它与Firefox一样遭受痛苦。 我们目前可以使用哪种方法最可

  • 本文向大家介绍vim 我可以使用哪些选项?,包括了vim 我可以使用哪些选项?的使用技巧和注意事项,需要的朋友参考一下 示例 如果您不知道应该使用哪些选项,则可能对该:options命令感兴趣。 这将打开一个列出所有Vim选项并显示其当前值的拆分。有26个部分显示您可以尝试的所有选项。 例如 在值行(例如set nowrap)上,您可以按CR切换值(如果它是二进制值)。在选项行(例如wrap lo

  • 主要内容:1) Docker,2) Go语言,3) Kubernetes,4) etcd,5) beego,6) martini,7) codis,8) delve所有的编程语言都反映了语言设计者对编程哲学的反思,通常包括之前的语言所暴露的一些不足地方的改进。Go语言从发布 1.0 版本以来备受众多开发者关注并得到广泛使用,Go语言的简单、高效、并发特性吸引了众多传统语言开发者的加入,而且人数越来越多。 使用Go语言开发的开源项目非常多。早期的Go语言开源项目只是通过Go语言与传统项目进行C语言

  • 谷歌(遗憾地)计划破坏存储权限,使应用程序无法使用标准文件API(和文件路径)访问文件系统。许多人反对它,因为它改变了应用程序访问存储的方式,在很多方面,它是一个受限的API。 因此,如果我们希望处理各种存储卷并访问其中的所有文件,我们将需要在未来的Android版本上完全使用SAF(存储访问框架)(在Android Q上,我们至少可以暂时使用一个标志来使用正常的存储权限)。 例如,假设您想创建一

  • 问题内容: 我是JAX-RS的新手,我试图了解注释的工作方式。 在javadoc中有六个等级的列表()。但是,我在网络上找到将this注释与其他类型一起使用的代码,例如: 是否有可以与此注释一起使用的受支持类型的列表?在执行标准之间,此列表是否会更改? 我目前正在试验Jersey,我担心自己写的代码无法移植到其他JAX-RS实现中。 问题答案: 铆接的JAX-RS 规范定义了你可以通过注入的所有标

  • 我是 JAX-RS 的新手,我正在尝试了解注释应该如何工作。 在javadoc中有一个包含六个类的列表(< code >应用程序、< code>UriInfo、< code >请求、< code>HttpHeaders、< code >安全上下文、< code >提供者)。但是,我在网上找到了将this批注用于其他类型的代码,例如: 是否有可用于此批注的支持类型列表?该列表在标准实施期间是否发生变