string
Strings in Go are created via double quotes:
str := "Hello, world!"
A notable difference between strings in Go and strings in JavaScript/TypeScript is that strings in Go are UTF-8 encoded while JavaScript/TypeScript strings are UTF-16 encoded.
Go strings vs JavaScript strings (UTF-8 vs UTF-16)
Section titled “Go strings vs JavaScript strings (UTF-8 vs UTF-16)”While technically JavaScript strings need more memory due to their UTF-16 encoding, the more obvious difference is how iteration works.
In Go, when you get the length of a string using len
, it returns the number of bytes in the string, not necessarily the number of characters. This is because Go uses UTF-8 encoding, which can use 1 to 4 bytes per character.
In JavaScript, the length
property returns the number of UTF-16 code units in the string, e.g:
const str = "é";console.log(str.length); // Output: 1 (UTF-16 code units)
Compared to Go:
str := "é"length := len(str)fmt.Println(length) // Output: 2 (bytes)
To represent the character é
in UTF-8, it takes 2 bytes. So Go when asked about the length will print 2
. But when dealing with strings you most likely don’t intend to work with the individual bytes but rather the “characters” in it. As such Go provides a special type called rune
which represents a single Unicode code point.
So given the above string, if we want to get the number of characters in it we can use the utf8.RuneCountInString
function:
import "unicode/utf8"// ...str := "é"length := utf8.RuneCountInString(str)fmt.Println(length) // Output: 1 (characters)
Now, we will get length 1 as expected.
Likewise if we want to iterate over the individual characters (runes) in a string we can use the for range
loop:
import "unicode/utf8"// ...str := "Medellín"for i, r := range str { fmt.Printf("Index: %d, Rune: %c\n", i, r)}
This will print:
Index: 0, Rune: MIndex: 1, Rune: eIndex: 2, Rune: dIndex: 3, Rune: eIndex: 4, Rune: lIndex: 5, Rune: lIndex: 6, Rune: íIndex: 7, Rune: n
We could also iterate over the string using a for
loop and len
but as mentioned this would give us the individual bytes:
str := "Medellín"for i := 0; i < len(str); i++ { fmt.Printf("Index: %d, Byte: %c\n", i, str[i])}
This will print:
Index: 0, Byte: MIndex: 1, Byte: eIndex: 2, Byte: dIndex: 3, Byte: eIndex: 4, Byte: lIndex: 5, Byte: lIndex: 6, Byte: ÃIndex: 7, Byte: Index: 8, Byte: n
Note that the í
character is represented by two bytes in UTF-8, which is why we see Ã
and
in the output.
String methods
Section titled “String methods”Most string methods in Go are part of the strings
package and don’t sit directly on the string type itself.
Here are some common string methods:
import "strings"// ...str := "Hello, world!"fmt.Println(strings.Contains(str, "world")) // Output: truefmt.Println(strings.HasPrefix(str, "Hello")) // Output: truefmt.Println(strings.HasSuffix(str, "!")) // Output: truefmt.Println(strings.Index(str, "world")) // Output: 7fmt.Println(strings.ToUpper(str)) // Output: HELLO, WORLD!fmt.Println(strings.ToLower(str)) // Output: hello, world!fmt.Println(strings.TrimSpace(" Hello, world! ")) // Output: Hello, world!fmt.Println(strings.Split(str, ", ")) // Output: [Hello world!]
String Concatenation
Section titled “String Concatenation”Like in JavaScript/TypeScript you can concatenate strings using the +
operator:
str1 := "Hello"str2 := "world"str3 := str1 + ", " + str2 + "!"fmt.Println(str3) // Output: Hello, world!
String Interpolation
Section titled “String Interpolation”While Go does have backticks you can’t use them for string interpolation, you need to use fmt.Sprintf
:
str := "world"greeting := fmt.Sprintf("Hello, %s!", str)fmt.Println(greeting) // Output: Hello, world!
Multiline Strings
Section titled “Multiline Strings”You can create multiline strings using backticks (however no string interpolation is possible):
str := `Hello,world!`fmt.Println(str)
This will print:
Hello,world!