Type of string letter confusion

Why a single letter in go is a string type:

myLetter := "S"
fmt.Println(reflect.TypeOf(myLetter))
//
// string

… but letter taken from the string as an table element is uint8:

myString := "String"
myLetter := myString[0]
fmt.Println(reflect.TypeOf(myLetter))
//
// uint8

… and when I use for-loop its int32 all of the sudden:

myString := "String"
	for _, v := range myString {
		fmt.Println(reflect.TypeOf(v))
                //
                // int32 (x5)
	}

This is soooo confusing me when I code, plus I need to write additional converting functions whenever I do something string-manipulation-related.

What is the reasoning behind this? Do you have any tricks to improve my workflow?

Hi @maykie,

Everything that is surrounded by double quotes is a literal string, no matter how long that string is.

An individual element of a string, accessed as myString[0] is always a byte type, which is an alias for uint8. There is no char type in Go; use byte instead.

To iterate over the bytes of a string, use a classic for loop: for i := 0; i < len(str); i++ { fmt.Print(str[i]) }

The range operator is Unicode-aware. Unlike a classic loop, a range loop iterates over the individual Unicode runes of a string. Runes are of type rune, which is an alias for int32.


(Side note: reflect.TypeOf() has no idea about type aliases.
And a tip: fmt.Printf("%T\n", v) does the same as fmt.Println(reflect.TypeOf(v)) but is shorter, and you don’t have to import reflect into your code.)

2 Likes