How to join a slice of strings in Go: top mistakes and how to avoid them
\n\nHave you ever been writing Go and suddenly thought: "I need to join all these strings into one, but how to do it correctly?" This question is one of the most popular on Stack Overflow (tens of thousands of views). It seems simple, right? But beginners (and not only) keep stepping on the same rake: slowing down code, wasting a lot of memory, or getting unexpected bugs.
\n\nIn this article, we'll break down three typical mistakes when joining a slice of strings in Go and show how to avoid them. You'll learn to choose the right tool for each task — from simple joining to high-load applications. Let's go!
\n\nWhy is this topic so important?
\n\nWorking with strings is the foundation of any programming language. In Go, strings are immutable. When you "join" two strings using the + operator, a new string is actually created, and the old ones are copied. In a loop, this turns into quadratic complexity O(n²). And if there are many strings (hundreds of thousands), the program can slow down or even crash with out of memory.
Furthermore, Go is a language where performance matters. Therefore, the standard library offers elegant solutions. Let's look at the most common mistakes.
\n\nMistake #1: Concatenation in a loop using +=
\n\nWhat it looks like in practice
\n\nLet's say you have a slice of strings:
\n\nwords := []string{"Go", "is", "awesome", "but", "only", "if", "you", "use", "the", "right", "tools"}\n\nThe most intuitive way is to iterate over the slice and add each word:
\n\nresult := ""\nfor _, w := range words {\n result += w + " "\n}\nfmt.Println(result) // "Go is awesome but only if you use the right tools "\n\nLooks logical, right? Yes. But this is a ticking time bomb.
\n\nWhy is this bad?
\n\n- \n
- Memory copying. Each iteration creates a new string, copying all previous data into it. For 1000 strings of 10 characters each, that's ~500,000 extra copies. \n
- Huge number of allocations. Instead of one string, you create n strings, each of which is later garbage collected. \n
- Unreadable code. It's easy to forget about spaces or separators. \n
When is this acceptable? Only if there are just 2-3 strings and you are writing a one-off script. For production — never.
\n\nMistake #2: Using strings.Join with an empty separator (and not understanding its power)
\n\nThe correct hero
\n\nThe Go standard library gives us strings.Join. This is the ideal solution for 90% of cases:
import "strings"\n\nwords := []string{"Go", "is", "awesome"}\nresult := strings.Join(words, " ")\nfmt.Println(result) // "Go is awesome"\n\nThe code reads like a book: "join words with a space". And it works fast — strings.Join pre-calculates the final string length and allocates memory exactly once.
How do people make mistakes?
\n\n- \n
- Forgetting the separator.
strings.Join(words, "")— joins everything together. Sometimes this is needed, but often it's a bug. \n - Using
strings.Joinfor single concatenation. Don't do this:strings.Join([]string{a, b}, ""). Just writea + b. \n - Not handling an empty slice.
strings.Join([]string{}, ",")returns an empty string. This is normal, but beginners expect an error. \n
// Example where Join is not suitable\ndata := []string{}\nresult := strings.Join(data, ",") // "" — empty, but sometimes "," is needed\n// Then you have to add a check:\nif len(data) > 0 {\n result = "," + strings.Join(data, ",")\n}\n\nConclusion: strings.Join is your friend. Use it alway