如何将 `func() *int` 转换为 `func() interface{}`?

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

How to convert from `func() *int` to `func() interface{}`?

问题

我想要一个类似以下函数的东西:

func decorateFn(fn func() interface{}) interface{} {
  decorate()

  return fn()
}

func decorateFnInt(fn func() *int) *int {
  return decorateFn(fn).(*int)
}

使用 decorateFn((func() interface{})(fn)).(*int) 是不起作用的。是否可能将 func() *int 转换为 func() interface{}?如果可以,应该如何转换?

英文:

I'd like to have something like the following function:

func decorateFn(fn func() interface{}) interface{} {
  decorate()

  return fn()
}

func decorateFnInt(fn func() *int) *int {
  return decorateFn(fn).(*int)
}

Using decorateFn((func() interface{})(fn)).(*int) doesn't work. Is it possible to convert func() *int to func() interface{}? If so, how?

答案1

得分: 4

使用go 1.18,你可以使用泛型来实现这一点-确保在编译时进行类型安全检查,而无需运行时类型断言:

func decorateFn[T any](fn func() T) T {
    decorate()

    return fn()
}

func decorateFnInt(fn func() *int) *int {
    return decorateFn(fn)
}

函数decorateFn的类型约束可以通过检查fn的类型在编译时推断出来。

链接:https://go.dev/play/p/AAByiBFRQch

编辑:如果你被困在go 1.17并且无法使用泛型,你可以使用interface{}作为函数参数,但是任何类型决策都必须在运行时执行。你可以尝试使用类型切换

func decorateFn(v interface{}) interface{} {
    decorate()

    switch t := v.(type) {

    case func() *int:
        return t()

    case func() *string:
        return t()

    default:
        panic(fmt.Sprintf("unsupported type: %T", v))
    }

}

链接:https://go.dev/play/p/gDXTPqA1tXL

英文:

With go 1.18 you can use generics to achieve this - ensuring compile-time type safety and no runtime type assertions:

func decorateFn[T any](fn func() T) T {
	decorate()

	return fn()
}

func decorateFnInt(fn func() *int) *int {
	return decorateFn(fn)
}

The function decorateFn's type constraint can be inferred at compile-time by inspecting fn's type.

https://go.dev/play/p/AAByiBFRQch


EDIT: if you are stuck on go 1.17 and cannot use generics, you can use interface{} for the function parameter, but any type decisions must be performed at runtime. You could try a type switch:

func decorateFn(v interface{}) interface{} {
	decorate()

	switch t := v.(type) {

	case func() *int:
		return t()

	case func() *string:
		return t()

	default:
		panic(fmt.Sprintf("unsupported type: %T", v))
	}

}

https://go.dev/play/p/gDXTPqA1tXL

huangapple
  • 本文由 发表于 2022年4月14日 01:38:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/71861716.html
匿名

发表评论

匿名网友

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

确定