使用指针接收器调用函数的 Go 语法

2024-06-26

在Go中,如果我定义一个带有指针的函数作为接收者,它是否应该只允许从指针调用该函数?为什么从值本身调用这个函数就可以,并且有同样的效果。

例如,在以下程序中: m1.reset() 和 m2.reset() 具有相同的效果。即使 m1 是一个值而 m2 是一个指针。

我有点困惑,因为有做同一件事的两种方法并且不确定该遵循哪一个。虽然大部分代码都遵循习俗使用指针字段调用函数。我错过了什么吗?

package main

    import "fmt"

    type MyStruct struct {
        X int
    }

    func (m *MyStruct) reset() {
        m.X = 0
    }

    func main() {
        m1 := MyStruct{1}
        m2 := &MyStruct{1}

        fmt.Println(m1.X)
        fmt.Println(m2.X)

        m1.reset()
        m2.reset()

        fmt.Println(m1.X)
        fmt.Println(m2.X)
    }

@jnml 提供了完美的文档规范解释,但我想添加一个基于您的代码示例。我认为你的重点应该少在于“为什么有两种方法可以做同一件事”,而应该更多地关注何时使用一种方法而不是另一种方法。以指针作为接收者的方法能够修改该接收者的值,而以值作为接收者的方法则不能。这是因为这些方法接收到copy接收器的。当您获得指针的副本时,您仍然可以修改它的值。当您收到该值的副本时,您在该方法中所做的更改只会更改副本,而不会更改原始值:

package main

import "fmt"

type MyStruct struct {
    X int
}

func (m *MyStruct) resetPtr() {
    m.X = 0
}

func (m MyStruct) resetValue() {
    m.X = 0
}

func main() {
    m1 := MyStruct{1}
    m2 := &MyStruct{1}

    fmt.Println("Original Values:", m1.X, m2.X)

    m1.resetPtr()
    m2.resetPtr()

    fmt.Println("After resetPtr():", m1.X, m2.X)

    m1 = MyStruct{1}
    m2 = &MyStruct{1}

    m1.resetValue()
    m2.resetValue()

    fmt.Println("After resetValue():", m1.X, m2.X)
}

Output

Original Values: 1 1
After resetPtr(): 0 0
After resetValue(): 1 1

您可以看到访问这些变量的方式并不是真正的问题。更多的是关于您可以在方法内部使用它们做什么,以及如何将它们作为参数传递给其他函数或方法(被复制)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用指针接收器调用函数的 Go 语法 的相关文章

  • 在 C++/CLI 中传递非托管指针

    我正在创建一个依赖于众多 C 静态库的 C CLI 包装器 DLL 一些函数调用需要传入非托管指针 我如何正确地传递它们 此外 其他函数期望 this 指针 作为 void 传入 传递 这个 的正确方法是什么 这是我的班级定义 public
  • 在 Go 中调用外部命令

    如何在GO中调用外部命令 我需要调用外部程序并等待它完成执行 在执行下一条语句之前 您需要使用执行包 http golang org pkg os exec 使用启动命令Command http golang org pkg os exec
  • Scala Vector 折叠语法(/: 和 :\ 和 /:\)

    有人可以提供一些例子来说明如何 and http www scala lang org archives downloads distrib files nightly docs library scala collection immut
  • 为什么结构体的字段是“非名称”[重复]

    这个问题在这里已经有答案了 这段代码不起作用 它抱怨 j Bar 是一个 非名字 package main import fmt import os type foo struct Bar string Baz int func main
  • 如何在 Docker 容器中持久保存 go 1.11 模块?

    我正在将 Go 1 10 应用程序迁移到 Go 1 11 这还包括从dep https golang github io dep to mod https github com golang go wiki Modules用于管理依赖关系
  • p2 = p1 和 *p2 = *p1 之间的区别

    代码来自这里 http www cplusplus com doc tutorial pointers http www cplusplus com doc tutorial pointers include
  • 解析:如何在Android中设置指针?

    在我当前的类 例如 A 中 我有一列是指向另一个类 例如 B 的指针 任何人都可以让我知道如何在 Android 中为该列设置值吗 我尝试从 B 类中获取所需的行作为 ParseObject 并执行以下操作 classAObject put
  • Matplotlib 中经常使用的不寻常的 Python 语法元素

    一个附带条件 我的问题的核心语法元素是 Python 语言 然而 这个元素经常出现在 Matplotlib 库中 这是我见过它的唯一上下文 因此 我不确定这是一般的 Python 语法问题还是特定于库的问题 我所知道的是 我找不到任何要点
  • 运行时错误:分配给 nil 映射中的条目

    我正在尝试生成一个地图 然后将其转换为 yaml 文件 如下所示 uid kasi cn Chaithra street fkmp nandan cn Chaithra street fkmp remya cn Chaithra stree
  • 非本地包中的本地导入

    我知道应该避免本地进口 但在这种情况下有特殊情况需要 这是一个私人仓库 heroku buildpack 在go get 由于服务器上缺少私钥 与绝对 URL 一起使用时会出现此阶段 现在我得到这个错误local import in non
  • 如果两个指针的地址相同,则更改其中一个指针的值

    我有一个问题 我看到两个指针的地址与这里的问题相同 两个指针的地址相同 https stackoverflow com q 19088153 1292348 蓝月亮也回答了 这让我产生了更多疑问 由于两个指针具有相同的地址 我想更改其中一个
  • **(双星/星号)和 *(星号/星号)在函数调用中意味着什么?

    在类似的代码中zip x or f k 做什么 and 分别是什么意思 Python 如何实现该行为 以及对性能有何影响 See also Expanding tuples into arguments https stackoverflo
  • 将堆分配的指针转换为指向 VLA 的指针是否安全?

    如果我有一个指向代表典型的堆分配空间的指针 行主二维数组 将此指针强制转换为 指向 VLA 的等效指针以方便下标 例子 Assuming m was allocated and initialized something like int
  • C语言中如何检查未初始化的指针

    我的计算机科学教授给我们布置了这个作业 基本上我们有这两个未初始化的全局指针 min ptr max ptr 我们正在写这个void spray paint char x int sz char tok char t 函数获取 tok 的值
  • JavaScript 对象声明语法 - 变量名作为属性

    JavaScript 为您提供了多种声明对象的方法 当您手头有大部分可用数据时 最方便的 在我看来 如下 var person name John age 23 object literal syntax 这个语法的一个奇怪之处在于它与以下
  • 如何修复解析 go.mod 模块将其路径声明为“x”,但需要为“y”

    我正在开发一个 go 项目 它依赖于original project 我现在想通过修改来更改该项目中的行为original project 所以我克隆了github com y original project to github com
  • 收集实时 GC 指标 - Golang

    Go 中是否有一种简单的方法来获取有关 GC 和堆大小的信息 以便将它们公开给监控仪表板 我查看了运行时包 但似乎没有任何东西可以做到这一点 理想情况下 这不需要任何开销 例如在分析模式下运行应用程序等 但应该做好生产准备 您可以使用GOD
  • 如何在 Go 中正确编写 JVM AES/CFB8 加密

    我在 Kotlin 中编写了一个小测试 使用 Cipher 实例和算法 AES CFB8 NoPadding 来加密一些文本 Hello 我的世界的东西 我现在尝试在 Go 中做同样的事情 但是我无法产生相同的结果 我尝试过的所有不同方法总
  • 解决不同包编译protobuf定义时Go包命名冲突

    我正在使用 protoc 创建一些 DTO 定义的结构如下 protobuf common proto api service csvdownload proto My csvdownload proto看起来像这样 syntax prot
  • Golang func main() 在除 main 之外的包中?

    在这种情况下 例如helloworld 包的名称是 main 还有一个func main 陈述 但我也看到过代码func main 这是在其他一些包中 然而 该代码似乎可以用作独立程序 那么拥有一个意味着什么func main 带有除以下之

随机推荐