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
在你的示例中,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类型定义的是一个函数类型,它接受Test和string参数并返回string,这与hey2的签名匹配,但与hey1不直接兼容。
问题在于do(hey1, "a")这一行。hey1是Test类型的方法,不能直接作为函数值传递。你需要使用方法表达式(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))
}
关键点说明:
- 方法表达式:
Test.hey1将方法转换为函数,其签名为func(Test, string) string,与MyFuncType匹配。 - 方法值:
t.hey1也生成一个函数值,但它的签名是func(string) string(接收者t已绑定),这与MyFuncType不匹配,会导致编译错误。在上面的示例中,do(t.hey1, "a")实际上会导致编译错误,因为类型不匹配。
如果你运行修正后的代码,输出会是:
func(main.Test, string) string
func(main.Test, string) string
这显示了两种方式都成功将函数/方法传递给了 do 函数,且它们的类型都与 MyFuncType 一致。

