Как эффективно конкатенировать строки в Go?

Ответ

Поскольку строки в Go иммутабельны, каждая операция конкатенации с помощью оператора + приводит к выделению новой памяти и копированию данных. При большом количестве объединений это становится неэффективным. Существует несколько способов для производительной конкатенации:

1. strings.Builder (Рекомендуемый способ)

Это наиболее предпочтительный и производительный способ для построения строк из нескольких частей. strings.Builder использует внутренний байтовый буфер, который растет по мере необходимости, минимизируя количество аллокаций.

var builder strings.Builder
// Можно заранее выделить память, если известен примерный размер
// builder.Grow(100)

builder.WriteString("Это первая часть. ")
builder.WriteString("Это вторая.")

result := builder.String() // "Это первая часть. Это вторая."
// После вызова .String() повторное использование builder'а безопасно

Преимущества: Максимальная производительность, минимальные аллокации.

2. strings.Join

Если у вас есть срез (slice) строк, которые нужно объединить с разделителем, strings.Join — самый чистый и эффективный способ.

parts := []string{"user", "local", "bin"}
path := strings.Join(parts, "/") // "user/local/bin"

Преимущества: Идиоматично и эффективно для объединения срезов.

3. fmt.Sprintf

Этот способ следует использовать, когда требуется не простое сложение, а форматирование строки по шаблону. Он менее производителен, чем strings.Builder для простой конкатенации, из-за парсинга строки формата.

name := "Alex"
age := 30
info := fmt.Sprintf("Пользователь: %s, Возраст: %d", name, age)

Преимущества: Гибкое форматирование.

4. Оператор +

Подходит для объединения небольшого, заранее известного количества строк (2-3). Компилятор Go оптимизирует такие простые случаи, но в циклах его производительность резко падает.

// Допустимо:
str := "hello" + " " + "world"

// Неэффективно в цикле:
var s string
for _, v := range mySlice {
    s += v // Плохая практика, много аллокаций
}

Итог:

  • Для циклов и сложного построения: всегда используйте strings.Builder.
  • Для объединения среза строк: используйте strings.Join.
  • Для форматирования: используйте fmt.Sprintf.
  • Для 2-3 строк: можно использовать +.