Golang中方法签名的使用与注意事项

Golang中方法签名的使用与注意事项

package main

import (
	"fmt"
	"reflect"
)

type Test struct {
	Str string
}
type MyFuncType func(Test, string) string

func (t Test) hey1(s string) string {
	return t.Str
}

func hey2(t Test, s string) string {
	return t.Str
}

func main() {
	do(hey1, "a")
	do(hey2, "a")
}

func do(f MyFuncType, s string) {
	fmt.Println(reflect.TypeOf(f))
}
# command-line-arguments
./compile13.go:23:5: undefined: hey1

更多关于Golang中方法签名的使用与注意事项的实战教程也可以访问 https://www.itying.com/category-94-b0.html

3 回复

在你的示例中,hey1 是 Test 结构体的方法。

这意味着你需要这样做:

var foo Test
do(test.hey1, "a")

hey1 和 hey2 并不相同。

func (t Test) hey1(s string) string 是 hey1 的签名
func hey2(t Test, s string) string 是 hey2 的签名。

签名指的是函数名称、输入参数和返回类型。

如果我有一个函数 func hello(s string) string,这与 function hello(s int) int 并不相同。

更多关于Golang中方法签名的使用与注意事项的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


你的意思是 ↓?

var foo Test
do(foo.hey1, "a")

这不是我想要的:这里我们传递给 func do() 的是 hey1 方法接收 foo 后的结果。 我想要的是方法本身的签名,以便将其作为变量传递,就像处理函数那样:

func do(f func(Test, string), s string) {
	//
}

既然上面的写法有效,而且方法就是函数,我想这样做:

func do(f (Test) func(string), s string) {
	//
}

但这会产生编译时语法错误

在Go语言中,方法签名和方法值的使用需要区分方法表达式和函数。从你的代码来看,hey1是一个方法(method),而hey2是一个函数(function)。MyFuncType类型定义的是一个函数类型,它接受Teststring参数并返回string,这与hey2的签名匹配,但与hey1不直接兼容。

问题在于do(hey1, "a")这一行。hey1Test类型的方法,不能直接作为函数值传递。你需要使用方法表达式(method expression)来获取一个函数值,该函数值的第一个参数是接收者。

以下是修正后的代码:

package main

import (
	"fmt"
	"reflect"
)

type Test struct {
	Str string
}

type MyFuncType func(Test, string) string

func (t Test) hey1(s string) string {
	return t.Str
}

func hey2(t Test, s string) string {
	return t.Str
}

func main() {
	t := Test{Str: "test"}
	
	// 使用方法表达式将方法hey1转换为函数值
	do(Test.hey1, "a")
	do(hey2, "a")
	
	// 或者使用方法值
	do(t.hey1, "a")
}

func do(f MyFuncType, s string) {
	fmt.Println(reflect.TypeOf(f))
}

关键点说明:

  1. 方法表达式Test.hey1 将方法转换为函数,其签名为 func(Test, string) string,与 MyFuncType 匹配。
  2. 方法值t.hey1 也生成一个函数值,但它的签名是 func(string) string(接收者 t 已绑定),这与 MyFuncType 不匹配,会导致编译错误。在上面的示例中,do(t.hey1, "a") 实际上会导致编译错误,因为类型不匹配。

如果你运行修正后的代码,输出会是:

func(main.Test, string) string
func(main.Test, string) string

这显示了两种方式都成功将函数/方法传递给了 do 函数,且它们的类型都与 MyFuncType 一致。

回到顶部