A quick update on my livestream: It’s on hold until February, as my family and I made a bit of a last-minute trip to visit family for the month of January, so I won’t be in my studio for a while.
Instantiations
…
When using a generic function, type arguments may be provided explicitly, or they may be partially or completely inferred from the context in which the function is used. Provided that they can be inferred, type argument lists may be omitted entirely if the function is:
- called with ordinary arguments,
- assigned to a variable with a known type
- passed as an argument to another function, or
- returned as a result.
In all other cases, a (possibly partial) type argument list must be present. If a type argument list is absent or partial, all missing type arguments must be inferrable from the context in which the function is used.
// sum returns the sum (concatenation, for strings) of its arguments. func sum[T ~int | ~float64 | ~string](x... T) T { … } x := sum // illegal: the type of x is unknown intSum := sum[int] // intSum has type func(x... int) int a := intSum(2, 3) // a has value 5 of type int b := sum[float64](2.0, 3) // b has value 5.0 of type float64 c := sum(b, -1) // c has value 4.0 of type float64 type sumFunc func(x... string) string var f sumFunc = sum // same as var f sumFunc = sum[string] f = sum // same as f = sum[string]inferred:
So the TL;DR; here is, if it’s possible to tell what types are needed from the context, you don’t need to provide them explicitly. For functions, at least, this is going to be the common case. Most often, we reference generic functions when they are called.
So when is this not enough?
Well here’s a contrived example:
func sum[T ~int | ~float64, R ~int | ~float64](x ...T) R {
var total T
for _, i := range x {
total += i
}
return R(total)
}
In this modified sum
function, the result type is distinct from the input type, meaning one could request the float64
value of summing two int
values. In this example, the result type cannot be inferred:
fmt.Println(sum(1,2,3)) // cannot infer R
So we need to provide the explicit types when we call the function:
fmt.Println(sum[int, int](1, 2, 3)) // Success!
Quotes from The Go Programming Language Specification Version of August 2, 2023