Golang中如何为any类型传递更具体的类型参数
Golang中如何为any类型传递更具体的类型参数 考虑以下代码片段(playground)
package main
import "fmt"
type Foo struct{}
func foo() (Foo, error) {
return Foo{}, nil
}
type Bar struct{}
func bar() (Bar, error) {
return Bar{}, nil
}
func Wrap(fn func() (any, error)) func() string {
return func() string {
d, err := fn()
if err != nil {
return err.Error()
} else {
return fmt.Sprint(d)
}
}
}
func main() {
_ = Wrap(foo)
_ = Wrap(bar)
}
尝试编译此代码会产生以下错误:
./prog.go:29:11: cannot use foo (value of type func() (Foo, error)) as func() (any, error) value in argument to Wrap
./prog.go:30:11: cannot use bar (value of type func() (Bar, error)) as func() (any, error) value in argument to Wrap
有没有办法修改 Wrap 的签名来允许这种情况?目前的一个解决方法是:
func main() {
_ = Wrap(func() (any, error) { return foo() })
}
但这相当繁琐。
更多关于Golang中如何为any类型传递更具体的类型参数的实战教程也可以访问 https://www.itying.com/category-94-b0.html
4 回复
感谢您的建议,但实际上有很多类型会让这再次变得繁琐。由于 Wrap 的实现实际上可以与 any 对象一起工作,因此没有必要人为地限制它。
更多关于Golang中如何为any类型传递更具体的类型参数的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
如果你使用泛型,可以创建一个比 any 限制性更强的泛型类型。例如,
func Wrap[T Foo | Bar](fn func() (T, error)) func() string {
...
}
你可以使用泛型。
将
func Wrap(fn func() (any, error)) func() string {
替换为
func Wrap[T any](fn func() (T, error)) func() string {
在Go中,any类型与具体类型之间的函数签名不兼容,但可以通过泛型来解决这个问题。以下是修改后的代码:
package main
import "fmt"
type Foo struct{}
func foo() (Foo, error) {
return Foo{}, nil
}
type Bar struct{}
func bar() (Bar, error) {
return Bar{}, nil
}
// 使用泛型类型参数T
func Wrap[T any](fn func() (T, error)) func() string {
return func() string {
d, err := fn()
if err != nil {
return err.Error()
} else {
return fmt.Sprint(d)
}
}
}
func main() {
// 现在可以直接传递foo和bar函数
wrappedFoo := Wrap(foo)
wrappedBar := Wrap(bar)
fmt.Println(wrappedFoo()) // 输出: {}
fmt.Println(wrappedBar()) // 输出: {}
}
或者,如果你需要保持Wrap函数接受func() (any, error)签名,但让调用更简洁,可以使用辅助函数:
func WrapAny[T any](fn func() (T, error)) func() string {
return Wrap(func() (any, error) {
return fn()
})
}
func main() {
// 使用辅助函数
_ = WrapAny(foo)
_ = WrapAny(bar)
}
泛型解决方案是最直接的方法,它允许Wrap函数接受返回任意具体类型的函数,同时保持类型安全。编译器会自动推断类型参数T,因此调用时不需要显式指定类型。

