4

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?

2
  • 1
    The length of the array cannot (yet?) be parameterised, but you can of course parameterise the element type, e.g. func foo[T any](arr [42]T). What is your actual use case? Commented Jan 28, 2023 at 7:39
  • As of the time of this writing, it's not possible. But from their GitHub issues it seems that a syntax like func [T any] f(array [...]T) is gaining traction. Commented Jun 3, 2024 at 23:42

1 Answer 1

5

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[:])
}
Sign up to request clarification or add additional context in comments.

2 Comments

Got it. I'll stick to flat array and stride way. By the way, why ~ needed in func foo[T ~[2]uint64]MyFunc(v T) {}.
It’s just an example, the tilde isn’t mandatory. But without the tilde, the function would accept only [2]uint64 as type param. That would make the example moot bc you might as well write func foo(v [2]uint64) {} without type param at all

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.