How to Convert String to Byte Slice in Go

In Go, converting a string to a byte slice is straightforward because strings are internally represented as UTF-8 encoded byte sequences.

In Go, converting a string to a byte slice is straightforward because strings are internally represented as UTF-8 encoded byte sequences. You can perform this conversion using a simple type cast []byte(s) for standard ASCII or UTF-8 data, or by using the utf8.DecodeRune functions if you need to handle specific Unicode rune logic, though the direct cast is sufficient for 99% of use cases.

Here are the two most common scenarios:

1. Direct Type Casting (Most Common) This is the idiomatic way to convert a string to a []byte. It creates a new slice and copies the underlying data. This is safe, fast, and works perfectly for any valid UTF-8 string.

package main

import "fmt"

func main() {
    s := "Hello, Go!"
    
    // Direct conversion
    b := []byte(s)
    
    fmt.Printf("Original string: %s\n", s)
    fmt.Printf("Byte slice: %v\n", b)
    fmt.Printf("Length: %d\n", len(b))
    
    // Modifying the byte slice does not affect the original string
    b[0] = 'h'
    fmt.Printf("Modified slice: %s\n", string(b))
    fmt.Printf("Original string unchanged: %s\n", s)
}

2. Handling UTF-8 Explicitly If you are dealing with raw binary data that might not be valid UTF-8, or if you need to ensure strict UTF-8 compliance before conversion, you can use the utf8 package. However, for standard string-to-byte conversion, the direct cast above is preferred because Go strings are guaranteed to be valid UTF-8.

package main

import (
    "fmt"
    "unicode/utf8"
)

func main() {
    s := "Café" // Contains non-ASCII character
    
    // Check if valid UTF-8 (optional, usually redundant for Go strings)
    if !utf8.ValidString(s) {
        fmt.Println("Invalid UTF-8")
        return
    }

    // Conversion
    b := []byte(s)
    
    // Note: 'é' takes 2 bytes in UTF-8
    fmt.Printf("Byte count: %d (string length is %d runes)\n", len(b), utf8.RuneCountInString(s))
}

Key Considerations:

  • Immutability: Strings in Go are immutable. Converting to a []byte allows you to modify the data, but changes to the slice will never reflect back in the original string.
  • Memory: The conversion []byte(s) allocates a new slice and copies the data. It does not share the underlying memory with the string.
  • Rune vs. Byte: Remember that len(s) returns the number of bytes, not the number of characters (runes). If you need the character count, use utf8.RuneCountInString(s).

Use the direct cast []byte(s) unless you have a specific requirement to validate encoding or handle invalid UTF-8 sequences.