qeatzy
qeatzy

Reputation: 1541

How to specify array as type constraints in Go generics?

During rewriting code in generics to reduce code duplication, there is one type that expect a [N]T as type constraints.

Is it possible to specify array as type constraints in Go? eg, [32768]byte or [100]uint64.

What if my function has to handle several array types with different lengths?

Upvotes: 4

Views: 1937

Answers (1)

blackgreen
blackgreen

Reputation: 44665

You can use arrays in type parameter constraints but you must specify the length:

func foo[T ~[2]uint64]MyFunc(v T) {}

This of course will not admit, say, type Foo [3]uint64 as type argument, because the lengths differ. Just like declaring array variables doesn't admit non-const length.

So this also works:

const length = 2

type C interface {
    ~[length]uint64
}

The notation [...]uint64{} is available only in composite literals, so that's not an option in constraints either.

This also implies that in order to specify more than one array type in the same constraint, you have to use a union term:

type C interface {
    ~[100]byte | ~[2]uint64 | ~[3]uint64
}

And yes, this is impractical if you have many possible array types that your function is supposed to accept. Depending on your actual use case, it might be worth to accept slices instead.

type C2 interface {
    ~[]byte | ~[]uint64
}

and use it as:

func foo[T C2](v T) { ... }
// or with unnamed constraint
func foo[T ~[]byte | ~[]uint64](v T) { ... }

// usage
func main() {
    twoArr := [2]uint64{10,20}
    foo(twoArr[:])

    threeArr := [3]uint64{10,20,30}
    foo(threeArr[:])
}

Upvotes: 4

Related Questions