Home > database >  go generics in interfaces
go generics in interfaces

Time:09-13

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

CodePudding user response:

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 currently cannot take type parameters. 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.

  • Related