Как происходит конкатенация строк в Go и какие есть эффективные альтернативы?

Ответ

В Go строки являются неизменяемыми (immutable). Это означает, что любая операция, изменяющая строку (включая конкатенацию), на самом деле создает в памяти новую строку и копирует в нее данные. Рассмотрим основные способы и их эффективность.

1. Оператор + или +=

Простой и читаемый способ для небольшого количества строк.

str := "hello" + " " + "world"

Недостаток: Неэффективен в циклах или при большом количестве операций, так как на каждой итерации создается новая промежуточная строка и происходит аллокация памяти.

2. strings.Builder

Самый эффективный способ для последовательного построения строки из множества частей, особенно в циклах. Он использует внутренний байтовый буфер ([]byte), который растет по мере необходимости, минимизируя количество аллокаций памяти.

var builder strings.Builder
parts := []string{"Hello", " ", "World", "!"}
for _, part := range parts {
    builder.WriteString(part) // Эффективно дописывает в буфер
}
result := builder.String() // "Hello World!"

3. strings.Join

Идеально подходит для соединения среза (slice) строк с заданным разделителем. Этот метод эффективен, так как заранее вычисляет необходимый размер и делает только одну аллокацию памяти для итоговой строки.

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

4. fmt.Sprintf

Предназначен в первую очередь для форматирования, а не простого соединения. Он менее производителен из-за необходимости парсить строку формата. Используйте его, когда нужно вставлять в строку значения разных типов в определенном формате.

result := fmt.Sprintf("User %s has ID %d", "Alex", 123)

Вывод:

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