Golang中方法调用时参数数量无效的问题如何解决

Golang中方法调用时参数数量无效的问题如何解决

package main

import (
        "fmt"
)

type test struct {
        name string
}

func (a test) show(b test) {
        fmt.Println(b.name)
}

func main() {
        test.show(test{name: "mother"})
}

上面的代码会报错,但下面的代码却能正常运行,我不明白为什么?

package main

import (
        "fmt"
)

type test struct {
        name string
}

func (a test) show(b test) {
        fmt.Println(b.name)
}

func main() {
        test.show(test{name: "mother"},test{name: "father"})
}

我不明白为什么当我向 show 方法传递两个参数时它能工作,而在声明中我只定义了一个类型。

另外,为什么打印出来的是 “father” 而不是 “mother”?


更多关于Golang中方法调用时参数数量无效的问题如何解决的实战教程也可以访问 https://www.itying.com/category-94-b0.html

2 回复

你的示例定义了一个名为 test 的类型,而你是在这个类型上直接调用函数,而不是在该类型的实例上调用。让我们将 show 方法的接收器改为指针,使代码看起来更“丑陋”,以便看清“奇怪”的事情发生在哪里:https://play.golang.org/p/T91W05TpbeZ

现在,我们修改代码,让你像调用方法一样调用它们,而不是在类型上调用函数:https://play.golang.org/p/MRq8Yh4djju

现在应该更清楚了,有一个“this”参数,然后是其他参数。既然我们这样看,我们可能想重构 show 函数,让它显示当前的测试,而不是作为参数传递的测试:https://play.golang.org/p/UgzaldqVL46

Go 中的方法调用有点类似于 C# 中的静态函数:它们是“语法糖”。

更多关于Golang中方法调用时参数数量无效的问题如何解决的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


这是一个关于Go语言方法接收器(receiver)的常见误解。让我详细解释:

问题分析

在Go中,方法声明 func (a test) show(b test) 实际上有两个参数:

  1. 接收器参数 a test - 这是方法的接收者
  2. 普通参数 b test - 这是方法的参数

代码解释

第一个代码的问题:

test.show(test{name: "mother"})

这里只传递了一个参数,但方法需要两个参数(接收器 + 参数),所以报错。

第二个代码为什么能工作:

test.show(test{name: "mother"}, test{name: "father"})

这里传递了两个参数:

  • 第一个 test{name: "mother"} 作为接收器 a
  • 第二个 test{name: "father"} 作为参数 b

方法内部打印的是参数 b.name,所以输出的是 "father"

正确的调用方式

通常我们通过实例调用方法,这样更清晰:

package main

import (
    "fmt"
)

type test struct {
    name string
}

func (a test) show(b test) {
    fmt.Println("接收器名字:", a.name)
    fmt.Println("参数名字:", b.name)
}

func main() {
    // 方式1:通过实例调用
    t1 := test{name: "mother"}
    t2 := test{name: "father"}
    t1.show(t2)  // 输出:接收器名字: mother, 参数名字: father
    
    // 方式2:通过类型直接调用(不推荐,容易混淆)
    test.show(t1, t2)  // 等同于 t1.show(t2)
}

关键点总结

  1. 方法接收器是隐式的第一个参数
  2. 通过类型直接调用方法时,需要显式传递接收器作为第一个参数
  3. 通过实例调用时,接收器是自动传递的

这就是为什么你的第二个代码能工作,并且打印的是 "father" 的原因。

回到顶部