gpt4 book ai didi

function - Golang 使用任意接口(interface)传递函数参数

转载 作者:IT王子 更新时间:2023-10-29 01:09:58 24 4
gpt4 key购买 nike

以下代码运行良好:

package main

import (
"fmt"
)

func WrapperFunc(fn func(int,int) int) int{
return fn(3,4)
}

func add(a,b int) int{
return a + b
}

func main(){
fmt.Println(WrapperFunc(add))
}

我想传递实现特定接口(interface)的附加参数。比如我修改代码如下:

import (
"fmt"
)

type RequestBody interface {
GetDescription() string
}

type LoginRequest struct {
Username string
Password string
}

func (lr LoginRequest) GetDescription() string{
return "cool function"
}

func WrapperFunc(fn func(int, int, RequestBody) int) int {
lr := LoginRequest{}
return fn(3, 4, lr)
}

func add(a, b int, lr LoginRequest) int {
fmt.Println(lr.GetDescription())
return a + b
}

func main() {
fmt.Println(WrapperFunc(add))
}

失败并出现以下错误:

cannot use add (type func(int, int, LoginRequest) int) as type func(int, int, RequestBody) int in argument to WrapperFunc

但是,当我没有按如下方式实现 GetDescription 时:

package main

import (
"fmt"
)

type RequestBody interface {
GetDescription() string
}

type LoginRequest struct {
Username string
Password string
}

func WrapperFunc(fn func(int, int, RequestBody) int) int {
lr := LoginRequest{}
return fn(3, 4, lr)
}

func add(a, b int, lr LoginRequest) int {
return a + b
}

func main() {
fmt.Println(WrapperFunc(add))
}

它因第二个错误而失败,因为接口(interface)未实现(如预期)。

cannot use lr (type LoginRequest) as type RequestBody in argument to fn:
LoginRequest does not implement RequestBody (missing GetDescription method)
cannot use add (type func(int, int, LoginRequest) int) as type func(int, int, RequestBody) int in argument to WrapperFunc

所以,它明白,在 WrapperFunc 主体中,我只能用 int 调用 fnint和实现GetDescriptionRequestBody接口(interface),但我仍然无法在函数阶段传递它。我怎样才能做到这一点?我想包装可以具有其类型可以更改的参数的函数。

最佳答案

问题是 WrapperFunc() 需要一个函数类型的值:

func(int, int, RequestBody) int

然后您尝试将 add 传递给它,它具有一个函数类型:

func(int, int, LoginRequest) int

2 function types如果两者具有相同的参数和结果类型,则它们是相等的。这在上面提到的 2 种函数类型中不成立:RequestBodyLoginRequest 是不同的类型,因此将这些作为(或其中)参数的函数类型是不同的类型。

如果您更改其参数以匹配所需的类型,则只能将 add 传递给 WrapperFunc():

func add(a, b int, lr RequestBody) int {
fmt.Println(lr.GetDescription())
return a + b
}

现在 add()WrapperFunc() 的参数中具有与 fn 相同的函数类型,因此您的代码将编译并运行.

输出(在 Go Playground 上试试)

cool function
7

注意事项:

现在 add() 中的 lr 参数属于 RequestBody 而不是 LoginRequest。您可以像使用 RequestBody 一样使用它,也就是您可以调用它的 GetDescription() 方法。在 WrapperFunc() 中,您无需更改任何内容,因为 LoginRequest 实现了 RequestBody,因此可以调用 fn( ) 的值为 LoginRequest,类型为 RequestBody 的接口(interface)值将自动隐式创建并传递给 fn (在你的例子中是 add()

请注意,在 add() 中,因为参数现在是 RequestBody,所以您不能引用 LoginRequest 的字段。如果实现该接口(interface)的值确实是 LoginRequest 类型的值,您可能会这样做,在这种情况下您可以使用 type assertion在需要时获取包装的 LoginRequest 值。

关于function - Golang 使用任意接口(interface)传递函数参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37253717/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com