Sometimes you want your Go function to accept either a string or a slice of bytes, at which point the user then has to convert whichever one they have to the version you chose:
func Process(s string) { /* … do stuff with s … */ }
// …
var someBytes = []byte(/* … */)
pkg.Process(string(someBytes))
But now, with the power of generics, we can pick a lane and do the conversion automatically:
func Process[S ~string | ~[]byte](s S) { /* … do stuff with string(s) … */ }
That is to say, we will accept any type whose underlying type is either string
or []byte
, and since both of those can be converted to string
we only need to add the conversion once inside the function. And, if we change our minds later, well, we can convert to the other instead, and the caller doesn't have to change anything.
Of course, this does come at a cost: The caller doesn't have to type out the conversion if they have bytes, but the conversion may still allocate, and that's now harder to see. But for cases where we're not pinching bytes, the notational convenience may be worthwhile.