Go Magic: string → []byte — 3 Ways to Convert a String to a Byte Array

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Introduction: Why is the question "How to assign string to bytes array" so popular?

\n\n

If you've ever written in Go (Golang) and faced the need to turn an ordinary string into a byte array ([]byte), you are not alone. The question "How to assign string to bytes array" on Stack Overflow gathers tens of thousands of views. It would seem, what's so difficult about it? Just take and assign. But Go is a strictly typed language, and you can't just take and assign a string to a byte slice. You need to know the correct techniques.

\n\n

In this article, we will break down converting string to bytes array in Go. I will show you three main approaches: from the simplest to the super-fast but dangerous. You will learn which method to choose depending on the task, and you will forever stop getting confused with these conversions.

\n\n

Let's go!

\n\n

A Bit of Theory: Why is a string not a byte array?

\n\n

Before diving into the code, let's understand why Go distinguishes between these two types. This knowledge will save you from a dozen bugs.

\n\n
    \n
  • string in Go is an immutable sequence of bytes. You cannot change a character of a string by index. The string is always stored as a read-only block of memory.
  • \n
  • []byte is a mutable slice of bytes. You can change its contents, add new elements, etc.
  • \n
\n\n

It is precisely because of this difference in "immutability" that Go requires explicit conversion. If the compiler allowed simply assigning a string to a byte array, you could accidentally change the "protected" data of the string. Therefore, assign string to bytes array always requires your conscious action.

\n\n

Approach #1: Explicit Type Conversion (Simplest)

\n\n

This is the first method that comes to every beginner's mind. And it works!

\n\n
package main\n\nimport "fmt"\n\nfunc main() {\n    myString := "Hello, Go!"\n    myBytes := []byte(myString)\n\n    fmt.Println(myBytes) // [72 101 108 108 111 44 32 71 111 33] — bytes in UTF-8\n    fmt.Println(string(myBytes)) // Convert back: "Hello, Go!"\n}\n
\n\n

Pros:

\n
    \n
  • Extremely simple and readable.
  • \n
  • Standard method, understandable to any Go developer.
  • \n
\n\n

Cons:

\n
    \n
  • Creates a new copy of the data in memory. If the string is very large (e.g., 10 MB), this can be costly in terms of memory and time.
  • \n
  • Not suitable for high-load systems where every nanosecond matters.
  • \n
\n\n

When to use: In 90% of cases. For ordinary applications, web services, and scripts, this is more than enough. Don't optimize where it's not needed.

\n\n

Approach #2: Using copy() (Controlled)

\n\n

Sometimes you already have a pre-allocated byte array, and you want to fill it with data from a string. This is where the copy function comes to the rescue.

\n\n
package main\n\nimport "fmt"\n\nfunc main() {\n    myString := "Go is awesome"\n    \n    // Create a byte slice of the required length\n    myBytes := make([]byte, len(myString))\n    \n    // Copy data from the string into the slice\n    n := copy(myBytes, myString)\n    \n    fmt.Printf("Bytes copied: %d\\n", n) // 13\n    fmt.Println(string(myBytes)) // "Go is awesome"\n}\n
\n\n

Note: copy copies only the number of bytes that fit into the destination slice. If the destination slice is shorter than the string, only its length will be copied. This is safer than explicit conversion if you are unsure about the size.

\n\n

Pros:

\n
    \n
  • Full control over the copying process.
  • \n
  • Safety: you won't go out of bounds of the array.
  • \n
  • Can be used for partial copying (substring).
  • \n
\n\n

Cons:

\n
    \n
  • Requires pre-allocation of memory (make).
  • \n
  • Still creates a copy of the data.

Blogs

Book Recommendations