Golang中"receiver appears in its own argument list"是什么意思

Golang中"receiver appears in its own argument list"是什么意思 我正在学习Go语言。在Go语言教程的“方法”主题中,我看到了以下句子:

方法是一种带有特殊接收者参数的函数。 接收者出现在其自身的参数列表中,位于 func 关键字和方法名之间。

“接收者出现在其自身的参数列表中”这部分是什么意思?这里指的是哪个参数列表?为什么称之为列表?一个方法可以应用于多种类型吗?

这真的让我很困惑。希望能在这里得到有经验的成员的解答。

参考: Go语言方法教程

4 回复

这可能不是最准确的表述。这里有一份详细的描述 The Go Programming Language Specification - The Go Programming Language。请注意结尾附近的这句话,这很可能是教程中“参数列表”描述的来源:“方法的类型是一个函数的类型,该函数以接收者作为第一个参数。”

更多关于Golang中"receiver appears in its own argument list"是什么意思的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


基本上,这意味着在需要函数类型的任何地方,都可以传递或赋值一个方法。例如:

Go Playground - Go 编程语言

Go 是一种开源编程语言,它使得构建简单、可靠且高效的软件变得容易。

感谢您提供的规范链接,它解答了我的疑惑。您提到的规范部分中的最后一句话后面紧接着“然而,以这种方式声明的函数并不是一个方法。”所以,无论从哪个角度看,“参数列表”这个措辞都显得没有意义。

我来自Java背景,我发现Go的语法,特别是在创建和使用用户定义类型及接口方面,确实不够明确直接。

让我看看在更熟悉这门语言之后,我的看法是否会有所改变。

在Go语言中,“receiver appears in its own argument list”指的是方法声明中接收者参数的特殊语法位置。让我通过代码示例来解释:

package main

import "fmt"

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

// 方法声明 - 接收者出现在参数列表中
func (r Rectangle) Area() float64 {
    return r.width * r.height
}

// 对比普通函数
func AreaFunc(r Rectangle) float64 {
    return r.width * r.height
}

func main() {
    rect := Rectangle{width: 10, height: 5}
    
    // 调用方法
    fmt.Println("方法调用:", rect.Area())  // 输出: 50
    
    // 调用普通函数
    fmt.Println("函数调用:", AreaFunc(rect))  // 输出: 50
}

关键解释:

  1. "参数列表"的含义: 在方法声明 func (r Rectangle) Area() float64 中:

    • (r Rectangle) 就是接收者参数列表
    • 虽然通常只有一个接收者参数,但它仍然被称为"参数列表"(语法上使用括号表示列表)
  2. 为什么说"出现在其自身的参数列表中": 接收者参数 (r Rectangle) 是方法签名的一部分,位于:

    • func 关键字之后
    • 方法名 Area 之前 这与普通函数的参数位置不同。
  3. 一个方法只能应用于一种类型: 每个方法都绑定到特定的接收者类型。要为不同类型添加相同功能的方法,需要分别定义:

type Circle struct {
    radius float64
}

type Triangle struct {
    base, height float64
}

// 为Circle类型定义Area方法
func (c Circle) Area() float64 {
    return 3.14 * c.radius * c.radius
}

// 为Triangle类型定义Area方法
func (t Triangle) Area() float64 {
    return 0.5 * t.base * t.height
}

func main() {
    shapes := []interface{}{
        Rectangle{width: 10, height: 5},
        Circle{radius: 7},
        Triangle{base: 8, height: 6},
    }
    
    // 每个类型都有自己的Area方法实现
    for _, shape := range shapes {
        switch s := shape.(type) {
        case Rectangle:
            fmt.Println("Rectangle area:", s.Area())
        case Circle:
            fmt.Println("Circle area:", s.Area())
        case Triangle:
            fmt.Println("Triangle area:", s.Area())
        }
    }
}
  1. 接收者可以是值类型或指针类型
type Counter struct {
    value int
}

// 值接收者
func (c Counter) GetValue() int {
    return c.value
}

// 指针接收者(可以修改原值)
func (c *Counter) Increment() {
    c.value++
}

func main() {
    counter := Counter{value: 0}
    counter.Increment()
    fmt.Println(counter.GetValue())  // 输出: 1
}

这种语法设计让Go的方法在语法上明确绑定到特定类型,同时保持了函数调用的简洁性。接收者参数列表虽然通常只有一个参数,但在语法结构上仍然被视为参数列表。

回到顶部