Golang中这类函数的作用是什么?求大神解答
Golang中这类函数的作用是什么?求大神解答 我难以理解这个函数的执行流程。
- 这个“内部”函数是一个匿名函数吗?只是想确认一下术语是否正确。
NewHandler函数应该返回一个sdk.Handler类型的对象,对吗?但内部函数返回的是一个指向sdk.Result的指针和一个错误对象。我不明白那里发生了什么,*sdk.Result, error怎么能作为一个单一的(并且是不同类型的)sdk.Handler被返回呢?
func NewHandler(keeper Keeper) sdk.Handler {
return func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) {
switch msg := msg.(type) {
case MsgSetName:
return handleMsgSetName(ctx, keeper, msg)
default:
return nil, sdkerrors.Wrap(sdkerrors.ErrUnknownRequest, fmt.Sprintf("Unrecognized nameservice Msg type: %v", msg.Type()))
}
}
}
sdk.Handler 的定义在这里供参考:cosmos-sdk/types/handler.go at v0.38.2 · cosmos/cosmos-sdk · GitHub
type Handler func(ctx Context, msg Msg) (*Result, error)
我知道代码本身肯定是正确的,我只是不理解这是如何工作的,也不确定正确的术语是什么,以便能够查找相关信息。
更多关于Golang中这类函数的作用是什么?求大神解答的实战教程也可以访问 https://www.itying.com/category-94-b0.html
- 你也可以将其理解为闭包。https://tour.golang.org/moretypes/25
- 我将
func(ctx Context, msg Msg) (*Result, error)解读为一个返回(*Result, error)的函数。因此type Handler func(ctx Context, msg Msg) (*Result, error)只是该函数的类型别名。所以func NewHandler(keeper Keeper) sdk.Handler {...}是一个名为NewHandler的函数,它返回一个Handler。
这是一个典型的Go语言高阶函数用法。NewHandler返回的是一个函数值,这个函数值符合sdk.Handler类型定义。
-
关于匿名函数:是的,
return func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) { ... }返回的是一个匿名函数(函数字面量)。 -
关于类型匹配:
sdk.Handler本身就是一个函数类型:
type Handler func(ctx Context, msg Msg) (*Result, error)
所以NewHandler返回的函数完全匹配这个类型签名。
让我用一个更简单的例子说明:
package main
import "fmt"
// 定义函数类型
type Handler func(int, string) (string, error)
// 返回Handler类型的函数
func NewHandler() Handler {
return func(x int, s string) (string, error) {
if x > 0 {
return fmt.Sprintf("Positive: %s", s), nil
}
return "", fmt.Errorf("negative number")
}
}
func main() {
handler := NewHandler()
// 调用返回的函数
result, err := handler(5, "test")
if err != nil {
fmt.Println("Error:", err)
} else {
fmt.Println("Result:", result) // 输出: Result: Positive: test
}
}
在你的代码中,NewHandler返回的匿名函数:
- 接收
ctx sdk.Context和msg sdk.Msg参数 - 返回
(*sdk.Result, error) - 这完全匹配
sdk.Handler类型的定义
这种模式在Go中很常见,特别是在需要创建闭包(捕获外部变量keeper)或实现中间件模式时。keeper参数被匿名函数捕获,形成了闭包,所以返回的函数可以访问keeper变量。
执行流程:
- 调用
NewHandler(keeper)返回一个函数 - 后续可以调用这个返回的函数:
handler(ctx, msg) - 函数内部根据
msg的具体类型进行路由处理
这就是为什么*sdk.Result, error能作为sdk.Handler返回的原因——sdk.Handler本身就是返回这两个值的函数类型。

