Skip to content

Instantly share code, notes, and snippets.

@creachadair
Last active March 11, 2024 15:36
Show Gist options
  • Save creachadair/20f9865eb7beb90aa09cb8a64617e3f7 to your computer and use it in GitHub Desktop.
Save creachadair/20f9865eb7beb90aa09cb8a64617e3f7 to your computer and use it in GitHub Desktop.
A cute trick with strings

Strings and Bytes: Together Again

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment