Golang中的函数与接收器func (r receiver)详解

Golang中的函数与接收器func (r receiver)详解 在"func (r receiver)"中 "r"是什么?它是一个标识符吗? 如果我的问题听起来很幼稚,请见谅。我没有其他地方可以问这样的问题

21 回复

我将其理解为"目标参数"。

更多关于Golang中的函数与接收器func (r receiver)详解的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


感谢您的意见,但我不认为您是正确的

这里主要是在讨论术语问题

这很有用

“目标参数”

非常有趣。请详细说明。

( r receiver

那么这个接收器被命名为r吗?

cherilexvold1974:

Vertex 在 Go 中有什么特殊意义吗?

没有,它只是那个特定示例中的一个类型名称。

https://tour.golang.org/methods/1

在这个例子中,Abs 方法拥有一个名为 vVertex 类型接收器。

说实话,不然它应该是什么呢?即使 receiver 是一个标识符……至少在你看到这个词的地方……

啊!我一直在寻找这个:方法是一种带有特殊接收器参数的函数。

顺便说一句,我发现我已经学到导览课程第二单元的第17页了?我已经把它添加为Chrome收藏夹三次了。我决定只要有时间就会继续完成这个导览课程。

您和其他人对导览课程的具体引用对我非常有帮助。

Vertex在Go语言中有什么特殊含义吗?

cherilexvold1974:

所以这个接收器被命名为 r?

是的。虽然它的类型是 receiver,但它不一定是方法的接收器,因为你展示的代码片段要么不完整(缺少实际的方法名、参数和返回类型),要么是一个函数的类型,该函数接收一个 receiver 类型的参数且不返回任何内容/void

https://tour.golang.org/methods/1

Go语言没有类。我不明白这意味着什么。

这个页面上的许多内容我都一无所知。

甚至receiver也是一个标识符。谢谢!

但这是您提到的部分:Abs方法有一个类型为Vertex名为v的接收器。

谢谢。我只需要坚持学习,最终会弄明白的。

这很有趣,但有点超出我的理解范围 然而这句话"所以,基于这一点,我相信你是给’receiver’起了个别名r,这样以后调用时只需输入r而不必拼写完整的receiver"非常有帮助

但实际情况并非如此!

r 并不是 receiver 的别名!在你展示的示例中,rreceiver 类型。函数/方法声明在语义和语法上都与 import 语句有本质区别。

import "fmt" /*从主包中获取"format"模块...你可以使用它来调用fmt.Println。你可以为"fmt"添加别名,例如:import f "fmt"
这样你就可以使用f.Println()来代替fmt.Println()。对于名称较长的导入包来说很有用。*/

这很有趣,但对我来说有点难以理解

而这句话"所以,基于此,我认为你是给’receiver’起了个别名r,这样在后续调用时,你只需要输入r而不需要完整拼写receiver。"非常有帮助

NobbZ:

方法名称、参数和返回类型,或者是接受单个参数的函数类型

还有一些术语几乎让我感到困惑,但又不完全如此。

方法,我完全没概念。

名称,我已经掌握了。

参数,我开始理解了,但还没有清晰的定义。

返回,我脑子里只知道它是返回某些内容的东西……所以有点模糊。

类型过去真的让我困惑。以前对我来说,类型是指你打字输入的东西,比如用打字机(我年纪大了)或计算机键盘输入。这个定义对我很有帮助:“数据的分类”

更具体地说,当Go语言提到标识符时,这个术语是Go语言特有的吗?和/或是编程领域专用的?还是我们应该将"标识符"理解为普通英语中的定义——“用于识别某物的人或事物”?在查找后者的过程中,我发现了这样的解释:“计算技术中用于识别或引用程序及其内部元素(如变量或数据集)的字符序列。”

我肯定是找对方向了。

虽然这个问题可能看起来很基础,但在我明确了解Go语言所有元素的定义之前,这个词对我来说就像外语一样陌生。

我在参加在线教程时做了笔记:

import "fmt" /*从主包中获取"format"模块...这样你就可以使用
fmt.Println。你可以为"fmt"添加别名,例如:import f "fmt"
这将允许你使用f.Println()而不是fmt.Println()。对于
长名称的导入可能很有用。*/

基于这一点,我认为你是给’receiver’起了别名r,这样在后续调用时,只需输入r而不必完整拼写receiver。这是我的猜测…如果有人发现我说错了请纠正我,因为我还在学习过程中。😛

你描述的是方法的接收器。它是导入的别名

package main

import (
	f "fmt"
)

func main() {
	f.Println("Hello, playground")
}

这里的 ffmt 的别名。这在避免命名冲突时很有用。

要了解接收器是什么,请阅读相关文档。一个很好的起点是 Go 语言之旅。此外,Go 程序设计语言这本书仍然是学习 Go 的非常好的指南。

不推荐通过胡乱猜测和道听途说来学习任何知识。

幸运的是,我生命中有重要的人与你们持不同意见,也有另一些人赞同你们的看法。其中一位是我的姐姐,她非常了解我,认为只要我下定决心做任何事都能成功。顺便提一下,我姐姐是位成功的系统工程师,她曾经高中辍学。她觉得我比她更聪明。

第二位是我的老师,他认为综合考虑所有因素后,我取得了巨大进步。我选择遵循这两位重要人士的指导,而不是你们这些试图打击我的人——我实在想不通你们的目的何在。你们何必在意呢?这难道不是我自己的事吗?

关于所谓的"合理时间内",我有一生的时间!即使我在精通Go语言之前去世或变得年老昏聩,我仍然认为学习它让我受益匪浅。所以请你们退后吧!😉(充满爱意地说)

我可以再次向您提及这个建议吗?

嗨 Cherolyn,

我不得不认同 Norbert 写的大部分内容。您已经在非常基础的阶段停滞了数月之久,未能取得在合理时间内熟练所需的那种进步。

我一直认为您所使用的教育资源对您来说并非最佳选择。

每个人的学习方式不同。有些人通过阅读书籍或观看视频学习得很好,而其他人则通过亲身示范学得更快。对于数学…

我担心对于您来说,Go语言和这个论坛并不是开始学习编程的好选择。

一个完全不同的方法可能是Scheme语言以及非常优秀且详尽的书籍《如何设计程序》(可在线获取)。请花些时间,不要过于简短地阅读这本书。投入几个小时或几天的时间尝试理解它所教授的内容。也许这是一种适合您的方法。

在Go语言中,func (r receiver) 声明中的 r 是一个接收器参数,它确实是一个标识符,用于在方法体内引用接收器实例。接收器可以是值类型或指针类型,它将该函数绑定到特定的类型上,使其成为该类型的方法。

详细说明:

  • 接收器 r:这是一个变量名(标识符),代表方法被调用时的实例。你可以自定义这个名称(例如 selfobj 等),但惯例是使用类型的缩写或一个简短的描述性名称。
  • 接收器类型receiver 指定了方法关联的类型。它可以是结构体、自定义类型或基本类型(通过 type 定义)。
  • 值接收器与指针接收器
    • 值接收器func (r Type) methodName(),操作的是接收器的副本。
    • 指针接收器func (r *Type) methodName(),操作的是接收器本身的引用,允许修改原始数据。

示例代码:

package main

import "fmt"

// 定义一个结构体类型
type Rectangle struct {
    width, height float64
}

// 值接收器方法:计算面积(不修改原始实例)
func (r Rectangle) Area() float64 {
    return r.width * r.height
}

// 指针接收器方法:缩放尺寸(修改原始实例)
func (r *Rectangle) Scale(factor float64) {
    r.width *= factor
    r.height *= factor
}

func main() {
    rect := Rectangle{width: 10, height: 5}
    
    // 调用值接收器方法
    area := rect.Area()
    fmt.Printf("Area: %.2f\n", area) // 输出: Area: 50.00
    
    // 调用指针接收器方法
    rect.Scale(2)
    fmt.Printf("After scaling: width=%.2f, height=%.2f\n", rect.width, rect.height) // 输出: After scaling: width=20.00, height=10.00
}

关键点:

  • r 是标识符,在方法内作为接收器实例使用。
  • 选择值或指针接收器取决于是否需要修改接收器或考虑性能(大结构体使用指针避免复制)。
  • Go自动处理值/指针转换:rect.Scale(2) 即使 Scale 定义为指针接收器,也能正确调用。
回到顶部