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 >= 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 >= 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(&b, "%d...", i) } b.WriteString("ignition") fmt.Println(b.String())<p>Хотя, конечно, мы можем использовать и<strong>bytes.Buffer</strong>.</p>
11
var bstrings.Builder fmt.Fprintf(&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