func GAddAll[E int, S ~[]E](e E, s S) S {
copyS := make(S, len(s))
for i, v := range s {
copyS[i] = v + e
}
return copyS
}
For the above code, if I instantiate it like this, it will give an error when running(cannot infer S)
b := GAddAll[int]
fmt.Printf("%v", b(3, []int{1, 2}))
But it works fine like this
fmt.Printf("%v", GAddAll[int](3, []int{1, 2}))
I want to know why.
Instantiation fails because S ~[]E has an approximate constraint, and there isn't enough type information to instantiate S.
When you assign the function value with:
b := GAddAll[int]
the function is already being instantiated. Quoting the spec:
A generic function that is is not called requires a type argument list for instantiation; if the list is partial, all remaining type arguments must be inferrable.
However S isn't inferrable. The only information available to the compiler is the type parameter E. After a first pass of substitution, the compiler is only able to infer the constraint ~[]E, which is now ~[]int, but the type argument S is still unknown.
Given that approximate type sets with tilde (~) are virtually infinite, there's no way to conclusively determine what S is — it could be type FooSlice []int — and instantiation fails.
So if you need to pass around the function value, you must instantiate by supplying both type parameters:
b := GAddAll[int, []int] // ok
fmt.Printf("%v", b(3, []int{1, 2}))
Instead with the call expression:
GAddAll[int](3, []int{1, 2})
the compiler still can't infer S from the type argument int, but it can infer it from the non-type argument []int{1,2}, and then instantiate the function.
A generic function that is called may provide a (possibly partial) type argument list, or may omit it entirely if the omitted type arguments are inferrable from the ordinary (non-type) function arguments.
As a clarification, if you were to remove the tilde from the S ~[]E, like this:
func GAddAll[E int, S []E](e E, s S) S {}
inference would succeed by supplying only E, because the type set of S's constraint would have cardinality 1 (an exact type).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With