Какие существуют способы конкатенации строк в Go? Какой из них наиболее эффективный и почему?

Ответ

В Go есть несколько способов объединения строк, и выбор оптимального зависит от ситуации.

1. Оператор + или +=
Самый простой и читаемый способ. Подходит для объединения небольшого, заранее известного количества строк.

str1 := "hello"
str2 := " world"
result := str1 + str2 // "hello world"
  • Недостаток: Строки в Go иммутабельны (неизменяемы). Каждая операция + создает новую строку и аллоцирует под нее память, что крайне неэффективно при большом количестве объединений в цикле.

2. fmt.Sprintf
Гибкий способ для форматирования строк, но является одним из самых медленных из-за парсинга строки формата.

result := fmt.Sprintf("%s %s", "hello", "world")
  • Когда использовать: Когда нужно сложное форматирование, а не простое объединение.

3. strings.Join
Идеальный вариант для объединения среза (slice) строк с использованием разделителя.

parts := []string{"hello", "world", "from", "go"}
result := strings.Join(parts, " ") // "hello world from go"
  • Преимущество: Высокоэффективен, так как делает только одну аллокацию памяти под итоговую строку.

4. strings.Builder (Наиболее эффективный для последовательного построения)
Это самый производительный способ для построения строки из множества частей, особенно в циклах.

parts := []string{"hello", " ", "world"}
var builder strings.Builder
// Можно заранее выделить память, если известен примерный размер
// builder.Grow(11)

for _, part := range parts {
    builder.WriteString(part)
}
result := builder.String() // "hello world"

Почему strings.Builder эффективен:

  • Минимум аллокаций: Под капотом он использует изменяемый срез байт ([]byte). Память для него выделяется с запасом и растет по мере необходимости, что минимизирует количество аллокаций.
  • Отсутствие лишних преобразований: В отличие от bytes.Buffer, strings.Builder напрямую работает со строками и не требует преобразований при вызове .String().

Итог:

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