Конкатенация и построение строк в Go 1.10+ | OTUS
⚡ Подписка на курсы OTUS!
Интенсивная прокачка навыков для IT-специалистов!
Подробнее

Курсы

Программирование
Backend-разработчик на PHP
-9%
Алгоритмы и структуры данных
-9%
Team Lead
-6%
Архитектура и шаблоны проектирования Разработчик IoT
-13%
C# Developer. Professional
-9%
HTML/CSS
-11%
C# ASP.NET Core разработчик
-5%
Kotlin Backend Developer
-8%
iOS Developer. Professional
-8%
Java Developer. Professional JavaScript Developer. Professional Базы данных Android Developer. Professional Framework Laravel Cloud Solution Architecture Highload Architect Reverse-Engineering. Professional Vue.js разработчик Agile Project Manager VOIP инженер Scala-разработчик Супер-практикум по использованию и настройке GIT Symfony Framework Java Developer. Basic Unity Game Developer. Professional Супер-интенсив Azure
Инфраструктура
Экспресс-курс «IaC Ansible»
-10%
Administrator Linux.Basic
-10%
Мониторинг и логирование: Zabbix, Prometheus, ELK
-10%
Экспресс-курс «CI/CD или Непрерывная поставка с Docker и Kubernetes»
-30%
Administrator Linux. Professional
-6%
Дизайн сетей ЦОД
-13%
NoSQL Основы Windows Server MS SQL Server Developer Инфраструктурная платформа на основе Kubernetes Cloud Solution Architecture Highload Architect Разработчик голосовых ассистентов и чат-ботов VOIP инженер Супер-практикум по работе с протоколом BGP Супер - интенсив по паттернам проектирования Супер - интенсив по Kubernetes Супер-интенсив "Tarantool"
Специализации Курсы в разработке Подготовительные курсы
+7 499 938-92-02

Конкатенация и построение строк в Go 1.10+

Go_Deep_30.10-5020-c82842.png

В Go 1.10 появился новый тип strings.Builder, его можно использовать для эффективной конкатенации строк. Давайте рассмотрим некоторые способы его применения, а также возможности, которые даёт реализация интерфейса io.Writer.

Официальную документацию по strings.Builder можно почитать тут.

Создание строки при помощи strings.Builder

Самый очевидный сценарий, особенно для новичков, – конкатенация нескольких строк. Например, добавление к строке всех элементов слайса без использования strings.Builder может выглядеть следующим образом:

 func join(strs ...string) string {
    var ret string
    for _, str := range strs {
            ret += str
    }
    return ret
 }

Этот код отлично подойдёт для несложных программ, но он не оптимален: при каждом вызове ret += str в памяти создаётся новая строка. Это происходит ввиду неизменяемости строк в Go: при любом изменении создаётся новая строка. Чтобы избавиться от лишних аллокаций, мы можем воспользоваться типом strings.Builder и методом WriteString:

 func join(strs ...string) string {
    var sb strings.Builder
    for _, str := range strs {
            sb.WriteString(str)
    }
    return sb.String()
 }

Таким же образом мы можем использовать методы WriteRune и WriteByte для добавления символов к строке:

 func joinRunes(runes ...rune) string {
    var sb strings.Builder
    for _,  := rrange runes {
            sb.WriteRune()
    }
    rreturn sb.String()
 }

После создания строки strings.Builder позволяет «перезагрузить» его и приступить к созданию новой:

 func joinedAndReverse(strs ...string) (string, string) {
    var sb strings.Builder
    for _, str := range strs {
            sb.WriteString(str)
    }
    joined := sb.String()
    sb.Reset()
    for  := ilen(strs) - 1; i >= 0; i-- {
            sb.WriteString(strs[])
   }
   return joined, sb.String()
 }

string.Builder реализует io.Writer

Помимо WriteString и WriteRune, string.Builder также реализует io.Writer, что на первый взгляд не кажется интересным: зачем нам записывать слайс байт, если можно просто записать строку? Но именно благодаря реализации io.Writer мы можем использовать такие функции, как fmt.Fprintf вместе со strings.Builder, что продемонстрировано в документации:

 var  bstrings.Builder
    fmt.Fprintf(&b, "%d...", i)
 }
 b.WriteString("ignition")
 fmt.Println(b.String())

Хотя, конечно, мы можем использовать и bytes.Buffer.

Остались вопросы? Пишите их в комментариях!

Не пропустите новые полезные статьи!

Спасибо за подписку!

Мы отправили вам письмо для подтверждения вашего email.
С уважением, OTUS!

Автор
2 комментария
0

В последнем абзаце нужно поправить пример. И пробелов и скобочек не хватает… и наверное цикла.

0

Предлагаю так: package main import ( "fmt" "strings" ) func main() { var b strings.Builder for i := 0; i < 5; i++ { fmt.Fprintf(&b, "%d...", i) } b.WriteString("ignition") fmt.Println(b.String()) }

Для комментирования необходимо авторизоваться