如何将具有任意返回类型的函数作为参数传递给另一个函数?

huangapple go评论86阅读模式
英文:

How to pass func with any return type as parameter into another function?

问题

要将具有任何可能输出的函数作为参数传递,您可以使用空接口类型interface{}作为函数参数和返回类型。这样可以接受任何类型的函数作为参数,并且在需要时可以将其转换为所需的类型。以下是修改后的代码示例:

func F(f func() interface{}) interface{} {
	return f()
}

func one() int {
	return 1
}

type A struct{}

func two() A {
	return A{}
}

func main() {
	a := F(func() interface{} { return one() })
	b := F(func() interface{} { return two() })
}

通过将函数类型更改为func() interface{},您可以将任何具有不同输出类型的函数传递给F函数。在main函数中,我们使用匿名函数来包装onetwo函数,并将其作为参数传递给F函数。

英文:
func F(f func()interface{})interface{} {
	return f()
}

func one() int {
	return 1
}
type A struct {}
func two() A {
  return A{}
}
func main() {

	a := F(one)
    b := F(two)
}

The code above will fail with error

cannot use one (type func() int) as type func() interface {} in argument to F
cannot use two (type func() A) as type func() interface {} in argument to F

My question is how to pass a func with any possible output as a parameter?

答案1

得分: 3

类型为int的值可以赋给interface{}类型的变量;而类型为func() int的值不能赋给类型为func() interface{}的变量。这在任何版本的Go语言中都是成立的。

不过,在Go 1.18中,你可以通过使用T any来实现你想要的效果,其中anyinterface{}的别名:

func Callf[T any](f func() T) T {
    return f()
}

func one() int {
    return 1
}

type A struct {}
func two() A {
  return A{}
}

func main() {
    a := Callf(one)
    b := Callf(two)

    fmt.Println(a) // 1
    fmt.Println(b) // {}
}

Playground: https://go.dev/play/p/zCB5VUhQpXE

英文:

A value of type int can be assigned to an interface{} variable; a value of type func() int can not be assigned to a value of type func() interface{}. This is true with any version of Go.

Though, what you are attempting to do can be achieved with Go 1.18, where you can easily parametrize the function with T any — where any is an alias of interface{}:

func Callf[T any](f func() T) T {
    return f()
}

func one() int {
    return 1
}

type A struct {}
func two() A {
  return A{}
}

func main() {
    a := Callf(one)
    b := Callf(two)

    fmt.Println(a) // 1
    fmt.Println(b) // {}
}

Playground: https://go.dev/play/p/zCB5VUhQpXE

huangapple
  • 本文由 发表于 2021年12月27日 18:01:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/70494034.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定