Wie encode []rune in []byte Verwendung von utf8 in golang?
Also es ist wirklich einfach zu entschlüsseln []byte
in eine []rune
(einfach werfen zu string
, dann cast zu []rune
sehr gut funktioniert, ich gehe davon aus, dass es standardmäßig auf utf8 und mit filler-bytes für die Invaliden). Meine Frage ist - wie werden Sie angenommen zu Dekodieren dies []rune
zurück []byte
im utf8-form?
Bin ich etwas fehlt, oder muss ich manuell aufrufen, EncodeRune für jede einzelne rune in meinem []rune
? Sicherlich gibt es einen encoder, ich kann einfach passieren eine Writer
zu.
- Siehe Die Go-Blog: Strings, bytes, Runen und Zeichen in Go.
- Ich habe gelesen, daß das Dokument mindestens 5 mal und finde nicht das, was ich suchte.
- Dann wird einem sogar grundlegenden Quelle: golang.org/ref/spec#Conversions_to_and_from_a_string_type Kombinieren Sie #3 und #4 in der Liste.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Können Sie einfach konvertieren Sie eine rune Scheibe (
[]rune
) zustring
die Sie konvertieren zurück zu[]byte
.Beispiel:
Ausgang (versuchen Sie es auf die Gehen Spielplatz):
Den Gehen Die Spezifikation: Umbauten erwähnt diesen Fall explizit: Die Konvertierung zu und von einem string-Typ, Punkt #3:
Beachten Sie, dass die obige Lösung–obwohl das einfachste sein kann–vielleicht nicht die effizienteste sein. Und der Grund ist, weil es zuerst schafft eine
string
Wert, wird eine "Kopie" der Runen in UTF-8 kodiert ist, dann kopiert es die backing-Stück der Zeichenfolge, um das Ergebnis-byte-slice (eine Kopie gemacht werden muss, weilstring
Werte sind unveränderlich, und, wenn das Ergebnis-slice-teilen Sie Daten mit derstring
wären wir in der Lage zu ändern, den Inhalt derstring
; für details, siehe golang: []byte(string) vs []byte(*string) und Immutable Strings und Zeiger-Adresse).Beachten Sie, dass ein intelligenter compiler erkennen könnte, dass die intermediate
string
Wert kann nicht bezeichnet werden und somit zu beseitigen, eine der Kopien.Kriegen wir vielleicht eine bessere performance durch die Verteilung einer single-byte-slice, und Kodieren Sie die Runen nacheinander hinein. Und dann sind wir fertig. Einfach das tun, können wir nennen die
unicode/utf8
- Paket zu Hilfe:Ausgabe von den oben genannten ist die gleiche. Versuchen Sie es auf die Gehen Spielplatz.
Beachten Sie, dass, um das Ergebnis-slice, wir hatten zu erraten, wie groß das Ergebnis-slice wird. Wir verwendeten eine maximale Schätzung, was die Anzahl der Runen, multipliziert mit der maximalen Anzahl von bytes, die ein rune kann codiert werden, um (
utf8.UTFMax
). In den meisten Fällen größer sein wird als nötig.Schaffen wir eine Dritte version, wo wir zuerst berechnen Sie die genaue Größe benötigt. Für diese verwenden wir die
utf8.RuneLen()
Funktion. Der Gewinn wird sein, dass wir nicht "Abfälle" Speicher, und wir haben nicht zu tun, eine endgültige schneiden (bs = bs[:count]
).Vergleichen Sie die Leistungen. Die 3 Funktionen (3 Versionen) zu vergleichen:
Und die benchmarking-code:
Und die Ergebnisse:
Als vermutet, die zweite version ist schneller und die Dritte version ist die Schnellste, obwohl der performance-Gewinn ist nicht sehr groß. Im Allgemeinen ist die erste, einfachste Lösung ist es bevorzugt, wenn das aber in einigen kritischen Teil Ihrer app (und viele hingerichtet-oft), die Dritte version könnte es Wert genutzt zu werden.
string <-> []byte
, aber ich habe nicht den Sprung aus[]rune -> string -> []byte