Ab Go 1.10+ gibt es strings.Builder
, hier.
Ein Builder wird verwendet, um effizient einen String mit Write-Methoden zu erstellen. Es minimiert das Kopieren von Speicher. Der Nullwert ist einsatzbereit.
Beispiel
Es ist fast dasselbe wie mit bytes.Buffer
.
package main
import (
"strings"
"fmt"
)
func main() {
// NULLWERT:
//
// Es ist von Anfang an einsatzbereit.
// Du musst es nicht initialisieren.
var sb strings.Builder
for i := 0; i < 1000; i++ {
sb.WriteString("a")
}
fmt.Println(sb.String())
}
Klicke hier, um dies im Playground zu sehen.
Unterstützte Schnittstellen
Die Methoden von strings.Builder
werden unter Berücksichtigung der vorhandenen Schnittstellen implementiert, sodass Sie einfach vom neuen Builder
-Typ in Ihrem Code umschalten können.
Methodensignatur
Schnittstelle
Beschreibung
Grow(int)
bytes.Buffer
Erhöht die Kapazität des Puffers um den angegebenen Betrag. Siehe bytes.Buffer#Grow für weitere Informationen.
Len() int
bytes.Buffer
Gibt die Anzahl der Bytes im Puffer zurück. Siehe bytes.Buffer#Len für weitere Informationen.
Reset()
bytes.Buffer
Setzt den Puffer zurück, um leer zu sein. Siehe bytes.Buffer#Reset für weitere Informationen.
String() string
fmt.Stringer
Gibt den Inhalt des Puffers als String zurück. Siehe fmt.Stringer für weitere Informationen.
Write([]byte) (int, error)
io.Writer
Schreibt die gegebenen Bytes in den Puffer. Siehe io.Writer für weitere Informationen.
WriteByte(byte) error
io.ByteWriter
Schreibt das gegebene Byte in den Puffer. Siehe io.ByteWriter für weitere Informationen.
WriteRune(rune) (int, error)
bufio.Writer
oder bytes.Buffer
Schreibt das gegebene Zeichen in den Puffer. Siehe bufio.Writer#WriteRune oder bytes.Buffer#WriteRune für weitere Informationen.
WriteString(string) (int, error)
io.stringWriter
Schreibt den gegebenen String in den Puffer. Siehe io.stringWriter für weitere Informationen.
Unterschiede zu bytes.Buffer
- Es kann nur wachsen oder zurücksetzen.
- Es hat einen integrierten
copyCheck
-Mechanismus, der verhindert, dass er versehentlich kopiert wird. In bytes.Buffer
kann man z.B. auf die zugrunde liegenden Bytes wie folgt zugreifen: (*Buffer).Bytes()
. strings.Builder
verhindert dieses Problem. Manchmal ist dies jedoch kein Problem, sondern stattdessen erwünscht. Zum Beispiel: Für das Peek-Verhalten, wenn die Bytes an einen io.Reader
übergeben werden usw.
bytes.Buffer.Reset()
spult vor und verwendet erneut den zugrunde liegenden Puffer, während strings.Builder.Reset()
es nicht tut, es trennt den Puffer.
Hinweis
- Kopieren Sie keinen
strings.Builder
-Wert, da er die zugrunde liegenden Daten zwischenspeichert.
- Wenn Sie einen
strings.Builder
-Wert teilen möchten, verwenden Sie einen Zeiger darauf.
Schau dir den Quellcode für weitere Details an, hier.
12 Stimmen
Noch eine Bank
1 Stimmen
Hinweis: Diese Frage und die meisten Antworten scheinen vor dem Hinzufügen von
append()
in die Sprache geschrieben worden zu sein, was eine gute Lösung dafür ist. Es wird genauso schnell wiecopy()
ausgeführt, aber das Slice wird zuerst erweitert, auch wenn dies bedeutet, dass ein neues zugrundeliegendes Array allokiert wird, wenn die Kapazität nicht ausreicht.bytes.Buffer
macht immer noch Sinn, wenn Sie seine zusätzlichen Komfortmethoden möchten oder wenn das Paket, das Sie verwenden, dies erwartet.10 Stimmen
Es ist nicht nur "sehr ineffizient"; es hat ein spezifisches Problem, mit dem jeder neue Nicht-CS-Mitarbeiter, den wir jemals eingestellt haben, in den ersten Wochen der Arbeit konfrontiert wird. Es ist quadratisch - O(n*n). Denken Sie an die Zahlenfolge:
1 + 2 + 3 + 4 + ...
. Es istn*(n+1)/2
, die Fläche eines Dreiecks mit der Basisn
. Sie reservieren die Größe 1, dann die Größe 2, dann die Größe 3 usw., wenn Sie unveränderliche Strings in einer Schleife anhängen. Diese quadratische Ressourcenverwendung äußert sich auf mehrere Weisen als nur diese.