Golang: Генерация строк в циклах
В Go строки — неизменяемы (immutable). Это значит, что при каждой операции конкатенации создаётся новая строка, а не изменяется существующая:
s := "Hello"
s += " "
s += "world"Код выше создает три строки в памяти, потому что строки в Go не модифицируются напрямую. Если таких операций много (например, при сборке HTML, SQL или при генерации отчёта), это приводит к лишним аллокациям и снижению производительности.
Для таких случаев стандартная библиотека Go предлагает эффективное решение — strings.Builder.
strings.Builder — это структура из пакета strings, предназначенная для эффективного построения строк. Он накапливает содержимое во внутреннем буфере, а финальную строку можно получить с помощью метода .String().
var builder strings.Builder
builder.WriteString("Hello")
builder.WriteString(" ")
builder.WriteString("world")
result := builder.String()
fmt.Println(result) // => Hello worldДля работы с рунами используется свой метод:
builder.WriteString("Hi")
builder.WriteByte(' ')
builder.WriteRune('世') // китайский символ
builder.WriteRune('界') // "界"
fmt.Println(builder.String()) // => Hi 世界Почему Builder быстрее
Каждый вызов + над строками в Go создает новую строку, копируя содержимое в новую память. Это дорого по производительности при большом числе операций. Builder же использует один буфер и растёт по мере необходимости, что сокращает число выделений памяти и операций копирования.
Пример: Объединение с разделителем
package main
import (
"fmt"
"strings"
)
func main() {
text := "hexlet"
var bld strings.Builder
for i, r := range text {
bld.WriteRune(r)
// Добавляем запятую, если это не последний символ
if i < len(text)-1 {
bld.WriteString(",")
}
}
result := bld.String()
fmt.Println(result) // => h,e,x,l,e,t
}Задание
Напиши функцию FilterString(), которая получает строку и символ. Она должна вернуть новую строку без всех букв, совпадающих с этим символом — неважно, большие они или маленькие (например, A и a считаются одинаковыми).
FilterString("If I look forward I win", 'i') // "f look forward wn"
FilterString("If I look forward I win", 'O') // "If I lk frward I win"Для приведения символов к нижнему регистру используйте функцию unicode.ToLower():
import "unicode"
r := 'A'
unicode.ToLower(r) // 'a'Полезное
Golang: Генерация строк в циклах
В Go строки — неизменяемы (immutable). Это значит, что при каждой операции конкатенации создаётся новая строка, а не изменяется существующая:
s := "Hello"
s += " "
s += "world"Код выше создает три строки в памяти, потому что строки в Go не модифицируются напрямую. Если таких операций много (например, при сборке HTML, SQL или при генерации отчёта), это приводит к лишним аллокациям и снижению производительности.
Для таких случаев стандартная библиотека Go предлагает эффективное решение — strings.Builder.
strings.Builder — это структура из пакета strings, предназначенная для эффективного построения строк. Он накапливает содержимое во внутреннем буфере, а финальную строку можно получить с помощью метода .String().
var builder strings.Builder
builder.WriteString("Hello")
builder.WriteString(" ")
builder.WriteString("world")
result := builder.String()
fmt.Println(result) // => Hello worldДля работы с рунами используется свой метод:
builder.WriteString("Hi")
builder.WriteByte(' ')
builder.WriteRune('世') // китайский символ
builder.WriteRune('界') // "界"
fmt.Println(builder.String()) // => Hi 世界Почему Builder быстрее
Каждый вызов + над строками в Go создает новую строку, копируя содержимое в новую память. Это дорого по производительности при большом числе операций. Builder же использует один буфер и растёт по мере необходимости, что сокращает число выделений памяти и операций копирования.
Пример: Объединение с разделителем
package main
import (
"fmt"
"strings"
)
func main() {
text := "hexlet"
var bld strings.Builder
for i, r := range text {
bld.WriteRune(r)
// Добавляем запятую, если это не последний символ
if i < len(text)-1 {
bld.WriteString(",")
}
}
result := bld.String()
fmt.Println(result) // => h,e,x,l,e,t
}Задание
Напиши функцию FilterString(), которая получает строку и символ. Она должна вернуть новую строку без всех букв, совпадающих с этим символом — неважно, большие они или маленькие (например, A и a считаются одинаковыми).
FilterString("If I look forward I win", 'i') // "f look forward wn"
FilterString("If I look forward I win", 'O') // "If I lk frward I win"Для приведения символов к нижнему регистру используйте функцию unicode.ToLower():
import "unicode"
r := 'A'
unicode.ToLower(r) // 'a'Полезное
Ваше упражнение проверяется по этим тестам
package solution
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestFilterString(t *testing.T) {
a := assert.New(t)
a.Equal("f look forward wn", FilterString("If I look forward I win", 'i'))
a.Equal("If I lk frward I win", FilterString("If I look forward I win", 'O'))
a.Equal("Hxlt", FilterString("Hexlet", 'e'))
a.Equal("Hello", FilterString("Hello", 'x')) // Символ отсутствует
a.Equal("", FilterString("", 'a')) // Пустая строка
}Решение учителя откроется через:
20:00
