HTML Diff
0 added 0 removed
Original 2026-01-01
Modified 2026-03-10
1 <p>Теги: go, программирование на golang, конкатенация, построение строк, io.writer, fmt.fprintf, writerune, writestring, writebyte, strings.builder</p>
1 <p>Теги: go, программирование на golang, конкатенация, построение строк, io.writer, fmt.fprintf, writerune, writestring, writebyte, strings.builder</p>
2 <p>В Go 1.10 появился новый тип<strong>strings.Builder</strong>, его можно использовать для эффективной<strong>конкатенации строк</strong>. Давайте рассмотрим некоторые способы его применения, а также возможности, которые даёт реализация интерфейса<strong>io.Writer</strong>.</p>
2 <p>В Go 1.10 появился новый тип<strong>strings.Builder</strong>, его можно использовать для эффективной<strong>конкатенации строк</strong>. Давайте рассмотрим некоторые способы его применения, а также возможности, которые даёт реализация интерфейса<strong>io.Writer</strong>.</p>
3 <p><em>Официальную документацию по<strong>strings.Builder</strong>можно почитать<a>тут</a>.</em></p>
3 <p><em>Официальную документацию по<strong>strings.Builder</strong>можно почитать<a>тут</a>.</em></p>
4 <h2>Создание строки при помощи strings.Builder</h2>
4 <h2>Создание строки при помощи strings.Builder</h2>
5 <p>Самый очевидный сценарий, особенно для новичков, - конкатенация нескольких строк. Например, добавление к строке всех элементов слайса без использования<strong>strings.Builder</strong>может выглядеть следующим образом:</p>
5 <p>Самый очевидный сценарий, особенно для новичков, - конкатенация нескольких строк. Например, добавление к строке всех элементов слайса без использования<strong>strings.Builder</strong>может выглядеть следующим образом:</p>
6 func join(strs ...string) string { var ret string for _, str := range strs { ret += str } return ret }<p>Этот код отлично подойдёт для несложных программ, но он не оптимален: при каждом вызове ret += str в памяти создаётся новая строка. Это происходит ввиду неизменяемости строк в Go: при любом изменении создаётся новая строка. Чтобы избавиться от лишних аллокаций, мы можем воспользоваться типом<strong>strings.Builder</strong>и методом<strong>WriteString</strong>:</p>
6 func join(strs ...string) string { var ret string for _, str := range strs { ret += str } return ret }<p>Этот код отлично подойдёт для несложных программ, но он не оптимален: при каждом вызове ret += str в памяти создаётся новая строка. Это происходит ввиду неизменяемости строк в Go: при любом изменении создаётся новая строка. Чтобы избавиться от лишних аллокаций, мы можем воспользоваться типом<strong>strings.Builder</strong>и методом<strong>WriteString</strong>:</p>
7 func join(strs ...string) string { var sb strings.Builder for _, str := range strs { sb.WriteString(str) } return sb.String() }<p>Таким же образом мы можем использовать методы<strong>WriteRune</strong>и<strong>WriteByte</strong>для добавления символов к строке:</p>
7 func join(strs ...string) string { var sb strings.Builder for _, str := range strs { sb.WriteString(str) } return sb.String() }<p>Таким же образом мы можем использовать методы<strong>WriteRune</strong>и<strong>WriteByte</strong>для добавления символов к строке:</p>
8 func joinRunes(runes ...rune) string { var sb strings.Builder for _, := rrange runes { sb.WriteRune() } rreturn sb.String() }<p>После создания строки<strong>strings.Builder</strong>позволяет "перезагрузить" его и приступить к созданию новой:</p>
8 func joinRunes(runes ...rune) string { var sb strings.Builder for _, := rrange runes { sb.WriteRune() } rreturn sb.String() }<p>После создания строки<strong>strings.Builder</strong>позволяет "перезагрузить" его и приступить к созданию новой:</p>
9 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 &gt;= 0; i-- { sb.WriteString(strs[]) } return joined, sb.String() }<h2>string.Builder реализует io.Writer</h2>
9 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 &gt;= 0; i-- { sb.WriteString(strs[]) } return joined, sb.String() }<h2>string.Builder реализует io.Writer</h2>
10 <p>Помимо WriteString и WriteRune,<strong>string.Builder</strong>также реализует<strong>io.Writer</strong>, что на первый взгляд не кажется интересным: зачем нам записывать слайс байт, если можно просто записать строку? Но именно благодаря реализации<strong>io.Writer</strong>мы можем использовать такие функции, как<strong>fmt.Fprintf</strong>вместе со<strong>strings.Builder</strong>, что продемонстрировано в документации:</p>
10 <p>Помимо WriteString и WriteRune,<strong>string.Builder</strong>также реализует<strong>io.Writer</strong>, что на первый взгляд не кажется интересным: зачем нам записывать слайс байт, если можно просто записать строку? Но именно благодаря реализации<strong>io.Writer</strong>мы можем использовать такие функции, как<strong>fmt.Fprintf</strong>вместе со<strong>strings.Builder</strong>, что продемонстрировано в документации:</p>
11 var bstrings.Builder fmt.Fprintf(&amp;b, "%d...", i) } b.WriteString("ignition") fmt.Println(b.String())<p>Хотя, конечно, мы можем использовать и<strong>bytes.Buffer</strong>.</p>
11 var bstrings.Builder fmt.Fprintf(&amp;b, "%d...", i) } b.WriteString("ignition") fmt.Println(b.String())<p>Хотя, конечно, мы можем использовать и<strong>bytes.Buffer</strong>.</p>
12 <p><em>Остались вопросы? Пишите их в комментариях!</em></p>
12 <p><em>Остались вопросы? Пишите их в комментариях!</em></p>
13  
13