Conversions to and from a string type

March 7, 2024

Before I dive in to today’s spec discussion… are you enjoying this series? If so, would you do me a favor and help spread the word? Can you share a link to this message with a fellow Gopher, or on your work chat?


Conversion to and from string types is a minefield of special cases in Go. So this will take at least a couple of days. Let’s dive in.

Conversions to and from a string type
  1. Converting a slice of bytes to a string type yields a string whose successive bytes are the elements of the slice.
string([]byte{'h', 'e', 'l', 'l', '\xc3', '\xb8'})   // "hellø"
string([]byte{})                                     // ""
string([]byte(nil))                                  // ""

type bytes []byte
string(bytes{'h', 'e', 'l', 'l', '\xc3', '\xb8'})    // "hellø"

type myByte byte
string([]myByte{'w', 'o', 'r', 'l', 'd', '!'})       // "world!"
myString([]myByte{'\xf0', '\x9f', '\x8c', '\x8d'})   // "🌍"

So right off the bat, we have a case that isn’t exactly a special case, but is definitely non-obvious to many.

The string hellø appears to have a length of 5 characters. But does Go agree?

fmt.Println(len("hellø")) // 6

No, it does not. And the clue as to why is staring at us: The last character, ø, is made up of two bytes. And len() returns the number of bytes, not “characters”, in the string.

But what if you want to know the number of characters? Well, that is possible, using the unicode package:

fmt.Println(utf8.RuneCountInString("hellø")) // 5

Quotes from The Go Programming Language Specification Language version go1.22 (Feb 6, 2024)


Share this

Direct to your inbox, daily. I respect your privacy .

Unsure? Browse the archive .

Related Content


Converting slices to byte or rune slices

No livestream today, as I’m traveling with my family. See you next week! Conversions to and from a string type … Converting a value of a string type to a slice of bytes type yields a non-nil slice whose successive elements are the bytes of the string. []byte("hellø") // []byte{'h', 'e', 'l', 'l', '\xc3', '\xb8'} []byte("") // []byte{} bytes("hellø") // []byte{'h', 'e', 'l', 'l', '\xc3', '\xb8'} []myByte("world!") // []myByte{'w', 'o', 'r', 'l', 'd', '!


Converting rune slices to strings

Yesterday we started through the list of rules and special cases for converting to and from string types. Let’s continue… Conversions to and from a string type … Converting a slice of runes to a string type yields a string that is the concatenation of the individual rune values converted to strings. string([]rune{0x767d, 0x9d6c, 0x7fd4}) // "\u767d\u9d6c\u7fd4" == "白鵬翔" string([]rune{}) // "" string([]rune(nil)) // "" type runes []rune string(runes{0x767d, 0x9d6c, 0x7fd4}) // "\u767d\u9d6c\u7fd4" == "白鵬翔" type myRune rune string([]myRune{0x266b, 0x266c}) // "\u266b\u266c" == "♫♬" myString([]myRune{0x1f30e}) // "\U0001f30e" == "🌎" I think this one is pretty intuitive.


Converting integers to strings

Sorry I missed yesterday. The family road trip ended later than expected, and I was too shot to write anything. Conversions to and from a string type … Finally, for historical reasons, an integer value may be converted to a string type. This form of conversion yields a string containing the (possibly multi-byte) UTF-8 representation of the Unicode code point with the given integer value. Values outside the range of valid Unicode code points are converted to "\uFFFD".

Get daily content like this in your inbox!

Subscribe