如何使函数接受实现通用接口的结构体?

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

How to make a function accept structs that implement generic interfaces?

问题

我有以下通用接口:

type Worker[input any, output any] interface {
    Process(input) output
}

我试图用以下方式实现该接口:

type IntWorker[i int, o int] struct{}

func (w *IntWorker[i, o]) Process(input i) o {
    fmt.Println("running i")
    return 1
}

当我尝试使用它时,出现以下错误:

mgr := internal.NewWorkManager()
iwkr := &IntWorker[int, int]{}
mgr.RegisterWorker(iwkr)

错误信息为:

cannot use iwkr (variable of type *IntWorker[int, int]) as internal.Worker[any, any] value in argument to : *IntWorker[int, int] does not implement internal.Worker[any, any] (wrong type for method Process)
    have Process(input int) int
    want Process(any) any

请注意最后一段,它说要求any,但实际上是int。我不确定如何修复这个问题,因为我原本以为可以将任何类型传递给any

该变量被传递给以下函数:

func (m *WorkManager) RegisterWorker(f Worker[any, any]) uuid.UUID

请问有什么我可以帮助你的吗?

英文:

I have the following generic interface

type Worker[input any, output any] interface {
	Process(input) output
}

I'm trying to implement the interface with the following

type IntWorker[i int, o int] struct{}

func (w *IntWorker[i, o]) Process(input i) o {
	fmt.Println("running i")
	return 1
}

When I try to use this I get the following error

mgr := internal.NewWorkManager()
iwkr := &IntWorker[int, int]{}
mgr.RegisterWorker(iwkr)


cannot use iwkr (variable of type *IntWorker[int, int]) as internal.Worker[any, any] value in argument to : *IntWorker[int, int] does not implement internal.Worker[any, any] (wrong type for method Process)
		have Process(input int) int
		want Process(any) any

Note the last segment, it says want any but have int. I'm not sure how to fix this since I was under the impression you can pass anything to any

The variable is passed to this function:

func (m *WorkManager) RegisterWorker(f Worker[any, any]) uuid.UUID

答案1

得分: 1

任何应该接受Worker接口的通用变体的函数必须是通用函数。

func TakesAnyWorker[input any, output any](w Worker[input, output]) { ... }

类型Worker[any, any]不是通用类型,只能与实现Process(any) any的值兼容,因为这是您的接口定义所规定的。

在您的示例中,该函数是一个方法,在Go 1.19中无法接受类型参数。如果单个WorkManager始终接受相同类型的Worker,那么您可以将WorkManager定义为一个相容的通用类型,如下所示:

type WorkManager[input any, output any] struct { ... }

func (m *WorkManager[input, output]) RegisterWorker(f Worker[input, output]) uuid.UUID

如果单个WorkManager需要接受不同类型的Worker,那么恐怕您面临的问题比通用解决方案更大,您将不得不使用常规接口和reflect

英文:

Any functions that should take generic variants of the Worker interface must themselves be generic functions.

func TakesAnyWorker[input any, output any](w Worker[input, output]) { ... }

The type Worker[any, any] is not a generic type, and is only compatible with values implementing Process(any) any as that is what your interface definition dictates.

In your example, the function is a method, which cannot take type parameters in Go 1.19. If a single WorkManager will always take Workers of the same type, then you can make the WorkManager a congruent generic type like this:

type WorkManager[input any, output any] struct { ... }

func (m *WorkManager[input, output]) RegisterWorker(f Worker[input, output]) uuid.UUID

If your single WorkManager needs to take Workers of differing types, then I'm afraid you have bigger problems than generics can solve and you'll be forced to use regular interfaces and reflect.

huangapple
  • 本文由 发表于 2022年9月13日 06:26:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/73695838.html
匿名

发表评论

匿名网友

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

确定