strings.Builder
Эффективно создавайте строки
«strings.Builder» — бесплатный урок Go Academy на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Go Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Go Academy содержит 4 уроков всего.
Цена конкатенации с помощью +
Поскольку строки неизменяемы, каждое выражение s = s + part создаёт совершенно новую строку и снова копирует все байты.
В цикле это становится медленным и приводит к лишнему расходу памяти.
package main
import "fmt"
func main() {
s := ""
for i := 0; i < 3; i++ {
s = s + "go "
}
fmt.Println(s)
}Знакомство с strings.Builder
strings.Builder увеличивает внутренний буфер и избегает повторного копирования. Вы записываете данные в него, а затем один раз считываете результат в конце.
Объявите его с помощью var b strings.Builder.
package main
import (
"fmt"
"strings"
)
func main() {
var b strings.Builder
b.WriteString("Hello")
fmt.Println(b.String())
}WriteString в цикле
Настоящий выигрыш проявляется в циклах. Многократно вызывайте WriteString, а затем один раз считайте результат с помощью String().
package main
import (
"fmt"
"strings"
)
func main() {
var b strings.Builder
for i := 0; i < 3; i++ {
b.WriteString("go ")
}
fmt.Println(b.String())
}Запись байтов и рун
Builder принимает не только целые строки:
WriteByteдобавляет один байт.WriteRuneдобавляет одну кодовую точку Unicode.
package main
import (
"fmt"
"strings"
)
func main() {
var b strings.Builder
b.WriteString("Go")
b.WriteByte('!')
b.WriteRune('語')
fmt.Println(b.String())
}Builder реализует io.Writer
Поскольку Builder соответствует интерфейсу io.Writer, его можно использовать с fmt.Fprintf, чтобы форматировать данные непосредственно в буфер.
package main
import (
"fmt"
"strings"
)
func main() {
var b strings.Builder
fmt.Fprintf(&b, "x=%d y=%d", 3, 4)
fmt.Println(b.String())
}Отслеживание длины
b.Len() сообщает, сколько байтов уже записано, не создавая итоговую строку.
package main
import (
"fmt"
"strings"
)
func main() {
var b strings.Builder
b.WriteString("hello")
fmt.Println(b.Len())
}Предварительное выделение с помощью Grow
Если Вы примерно знаете размер результата, сначала вызовите b.Grow(n). Это зарезервирует ёмкость и предотвратит повторное изменение размера буфера.
package main
import (
"fmt"
"strings"
)
func main() {
var b strings.Builder
b.Grow(64)
for i := 0; i < 5; i++ {
b.WriteString("item ")
}
fmt.Println(b.String())
}Сброс Builder
b.Reset() очищает буфер, чтобы тот же Builder можно было использовать для следующей строки.
package main
import (
"fmt"
"strings"
)
func main() {
var b strings.Builder
b.WriteString("first")
b.Reset()
b.WriteString("second")
fmt.Println(b.String())
}Не копируйте Builder
strings.Builder нельзя копировать после первого использования. Передавайте его по указателю (*strings.Builder).
package main
import (
"fmt"
"strings"
)
func add(b *strings.Builder, word string) {
b.WriteString(word)
}
func main() {
var b strings.Builder
add(&b, "shared ")
add(&b, "builder")
fmt.Println(b.String())
}Создание строки CSV
Практический пример: эффективно соберите строку, разделённую запятыми, с помощью Builder.
package main
import (
"fmt"
"strings"
)
func main() {
fields := []string{"id", "name", "age"}
var b strings.Builder
for i, f := range fields {
if i > 0 {
b.WriteByte(',')
}
b.WriteString(f)
}
fmt.Println(b.String())
}Когда использовать Builder
Используйте strings.Builder, когда нужно объединить много фрагментов, особенно внутри циклов.
Для однократного объединения известного среза проще использовать strings.Join, который работает так же быстро.
package main
import (
"fmt"
"strings"
)
func main() {
var b strings.Builder
for i := 1; i <= 3; i++ {
fmt.Fprintf(&b, "[%d]", i)
}
fmt.Println(b.String())
}Быстрая проверка
Почему в цикле стоит предпочесть Builder многократной конкатенации с помощью +?
Повторение: strings.Builder
Вы научились эффективно создавать строки:
- Объявляйте Builder с помощью
var b strings.Builder. - Добавляйте данные через
WriteString,WriteByte,WriteRuneилиfmt.Fprintf. - При необходимости заранее вызывайте
Grow, один раз считывайте результат с помощьюString()и никогда не копируйте Builder.
package main
import (
"fmt"
"strings"
)
func main() {
var b strings.Builder
b.Grow(16)
b.WriteString("Go ")
b.WriteString("builder!")
fmt.Println(b.String())
}Часто задаваемые вопросы
Урок «strings.Builder» бесплатный?
Да — полный текст урока «strings.Builder» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Go Academy, подпишись на CoddyKit PRO. Курс Go Academy содержит 4 уроков всего.
Чему я научусь в уроке «strings.Builder»?
Эффективно создавайте строки Ты практикуешь Go Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Go Academy?
Предыдущий опыт не требуется. Go Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.
Сколько времени занимает урок «strings.Builder»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Go Academy?
Да. Каждый урок Go Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Руны и байты
- Функции пакета strings
- strings.Builder
- Unicode и utf8