ZetCode

Golang String Type

last modified May 8, 2025

This tutorial offers a detailed exploration of Go's built-in string type, providing a comprehensive guide to its usage. Through practical examples, we'll cover fundamental concepts, common operations, and best practices to help you efficiently manipulate and process string data in Go.

In Go, the string type represents an immutable sequence of bytes, making it ideal for storing and manipulating textual data, including Unicode characters. Strings can be defined in two primary ways: using double quotes ("...") for interpreted strings, where escape sequences like \n (newline) are recognized, or using backticks (`...`) for raw strings, which preserve exact formatting and special characters without escaping rules. The immutability of strings means that any modification results in the creation of a new string rather than altering the existing one.

By default, Go strings are encoded in UTF-8, ensuring efficient handling of international characters and compatibility with modern text-processing applications. They support essential operations such as indexing, slicing, and concatenation, allowing developers to extract substrings or build dynamic text structures.

Additionally, Go provides a rich set of built-in functions within the strings package, enabling advanced text manipulation tasks such as case conversion, trimming, searching, and splitting. Understanding these capabilities is crucial for writing efficient and maintainable Go programs.

Basic string operations

This example demonstrates basic string operations including concatenation, length, and indexing. Strings in Go are zero-indexed like arrays.

Note: String indices refer to bytes, not necessarily characters.
basic_string.go
package main

import "fmt"

func main() {

    s1 := "Hello"
    s2 := "世界" // "World" in Chinese
    
    // Concatenation
    greeting := s1 + " " + s2
    fmt.Println(greeting)
    
    // Length in bytes
    fmt.Println("Length of s1:", len(s1))
    fmt.Println("Length of s2:", len(s2))
    
    // Accessing characters
    fmt.Println("First character of s1:", string(s1[0]))
    fmt.Println("First byte of s2:", s2[0])
}

The example shows string concatenation with +, length with len, and byte access with indexing. Note that len returns bytes, not rune count.

String Iteration in Go

In Go, strings can be iterated using different techniques depending on whether you need to process individual bytes or full Unicode characters (runes). Understanding these approaches is essential for efficient text handling, especially when working with multilingual data or special characters.

string_iteration.go
package main

import "fmt"

func main() {

    s := "Hello 世界"
    
    fmt.Println("Byte iteration:")
    for i := 0; i < len(s); i++ {
        fmt.Printf("%x ", s[i])
    }
    fmt.Println()
    
    fmt.Println("Rune iteration:")
    for index, runeValue := range s {
        fmt.Printf("%#U starts at byte position %d\n", runeValue, index)
    }
}

Using a for loop with indexing iterates over the string at the byte level, which is useful for low-level operations but may split multi-byte characters. Since Go strings use UTF-8 encoding, non-ASCII characters, such as those in "世界", are represented by multiple bytes. Consequently, iterating over bytes alone can produce incomplete or unintended results when handling Unicode text.

On the other hand, iterating using the range keyword automatically decodes UTF-8 runes, ensuring that each Unicode character is treated correctly as a single unit. This method is generally preferred when processing text, as it respects character boundaries and prevents accidental fragmentation of multibyte characters.

String manipulation

The strings package provides many useful functions for string manipulation. This example shows common operations like trimming, splitting, and replacing.

string_manipulation.go
package main

import (
    "fmt"
    "strings"
)

func main() {

    s := "   Hello, World!   "
    
    // Trimming whitespace
    trimmed := strings.TrimSpace(s)
    fmt.Printf("Trimmed: '%s'\n", trimmed)
    
    // Splitting
    parts := strings.Split(trimmed, ",")
    fmt.Println("Split parts:", parts)
    
    // Replacement
    replaced := strings.Replace(trimmed, "World", "Gopher", 1)
    fmt.Println("Replaced:", replaced)
    
    // Case conversion
    fmt.Println("Upper:", strings.ToUpper(trimmed))
    fmt.Println("Lower:", strings.ToLower(trimmed))
}

The strings package is essential for string processing in Go. It provides functions for searching, modifying, and analyzing strings efficiently.

String conversion

Strings often need conversion to/from other types like byte slices or rune slices. This example demonstrates common conversions.

string_conversion.go
package main

import (
    "fmt"
    "strconv"
)

func main() {

    // String to byte slice
    s := "Hello"
    byteSlice := []byte(s)
    fmt.Println("Byte slice:", byteSlice)
    
    // Byte slice to string
    newStr := string(byteSlice)
    fmt.Println("Back to string:", newStr)
    
    // String to rune slice
    runeSlice := []rune("世界")
    fmt.Println("Rune slice:", runeSlice)
    
    // Number to string
    numStr := strconv.Itoa(42)
    fmt.Println("Number as string:", numStr)
    
    // String to number
    num, _ := strconv.Atoi("42")
    fmt.Println("String as number:", num)
}

Conversions between strings and byte/rune slices are common for processing. The strconv package handles numeric conversions with additional control.

String formatting

Go's fmt package provides powerful string formatting capabilities. This example shows common formatting verbs and their usage.

string_formatting.go
package main

import "fmt"

func main() {

    name := "Alice"
    age := 30
    height := 5.7
    
    // Basic formatting
    fmt.Printf("Name: %s, Age: %d\n", name, age)
    
    // Floating point precision
    fmt.Printf("Height: %.1f feet\n", height)
    
    // Padding and alignment
    fmt.Printf("|%10s|%5d|\n", name, age)
    fmt.Printf("|%-10s|%-5d|\n", name, age)
    
    // String building with Sprintf
    info := fmt.Sprintf("%s is %d years old", name, age)
    fmt.Println("Constructed string:", info)
}

The fmt package's formatting verbs provide precise control over string output. Sprintf builds strings without printing them, useful for string construction.

Source

Go language specification

This tutorial covered the string type in Go with practical examples of common string operations and manipulations.

Author

My name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than ten years of experience in teaching programming.

List all Golang tutorials.