Was ist ein rune
in Go?
Ich habe gegoogelt, aber Golang sagt nur in einer Zeile: rune
ist ein Alias fürint32
.
Aber wie kommt es, dass Ganzzahlen überall verwendet werden, wie wenn Fälle ausgetauscht werden?
Das Folgende ist ein Funktionsaustauschfall. Was ist das alles <=
und -
?
Und warum gibt switch
es keine Argumente?
&&
sollte bedeuten und aber was ist das r <= 'z'
?
func SwapRune(r rune) rune {
switch {
case 'a' <= r && r <= 'z':
return r - 'a' + 'A'
case 'A' <= r && r <= 'Z':
return r - 'A' + 'a'
default:
return r
}
}
Die meisten von ihnen stammen von http://play.golang.org/p/H6wjLZj6lW
func SwapCase(str string) string {
return strings.Map(SwapRune, str)
}
Ich verstehe, dass dies eine Zuordnung ist rune
, string
damit die ausgetauschte Zeichenfolge zurückgegeben werden kann. Aber ich verstehe nicht, wie genau rune
oder byte
funktioniert hier.
Antworten:
Runenliterale sind nur 32-Bit-Ganzzahlwerte ( sie sind jedoch untypisierte Konstanten, sodass sich ihr Typ ändern kann ). Sie repräsentieren Unicode-Codepunkte. Zum Beispiel ist das Runenliteral
'a'
tatsächlich die Zahl97
.Daher ist Ihr Programm ziemlich gleichbedeutend mit:
Es sollte offensichtlich sein, wenn Sie sich die Unicode-Zuordnung ansehen, die mit ASCII in diesem Bereich identisch ist . Darüber hinaus ist 32 tatsächlich der Versatz zwischen dem Groß- und Kleinbuchstaben des Zeichens. Also durch Zugabe
32
zu'A'
, man bekommt ,'a'
und umgekehrt.quelle
unicode.ToLower(r rune) rune
.func SwapRune(r rune) rune { if unicode.IsUpper(r) { r = unicode.ToLower(r) } else { r = unicode.ToUpper(r) }; return r }
Aus den Versionshinweisen von Go lang: http://golang.org/doc/go1#rune
Rune ist ein Typ. Es belegt 32 Bit und soll einen Unicode- CodePoint darstellen . Als Analogie hat der in 'ASCII' codierte englische Zeichensatz 128 Codepunkte. Somit kann in ein Byte (8bit) gepasst werden. Ausgehend von dieser (fehlerhaften) Annahme behandelte C Zeichen als "Bytes"
char
und "Zeichenfolgen" als "Folge von Zeichen"char*
.Aber rate mal was. Es gibt viele andere Symbole, die von Menschen erfunden wurden, außer den 'abcde ..'-Symbolen. Und es gibt so viele, dass wir 32 Bit benötigen, um sie zu codieren.
In Golang
string
ist a dann eine Folge vonbytes
. Da jedoch mehrere Bytes einen Runencodepunkt darstellen können, kann ein Zeichenfolgenwert auch Runen enthalten. Es kann also in a konvertiert[]rune
werden oder umgekehrt.Das Unicode-Paket http://golang.org/pkg/unicode/ kann einen Vorgeschmack auf den Reichtum der Herausforderung geben.
quelle
rune
ähnlich istint32
und viele Bits enthält.string
ist eine Folge vonrune
s" - ich glaube nicht, dass das stimmt? Go blog : "Ein String ist nur ein Bündel von Bytes"; Go lang spec : "Ein String-Wert ist eine (möglicherweise leere) Folge von Bytes"not bytes
. Dann könnte man sagen: "Strings bestehen aus Runen und Runen aus Bytes" So etwas. Dann wieder. es ist nicht ganz wahr.Ich habe versucht, meine Sprache einfach zu halten, damit ein Laie versteht
rune
.Eine Rune ist ein Charakter. Das ist es.
Es ist ein einzelnes Zeichen. Es ist ein Zeichen aus jedem Alphabet aus jeder Sprache von überall auf der Welt.
Um einen String zu bekommen, verwenden wir
ODER
Eine Zeichenfolge unterscheidet sich von einer Rune. In Runen verwenden wir
Jetzt ist eine Rune auch ein Alias für
int32
... Äh was?Der Grund, warum Rune ein Alias
int32
ist, liegt darin, dass wir dies bei Codierungsschemata wie den folgenden sehenJedes Zeichen ist einer Nummer zugeordnet, und daher ist es die Nummer, die wir speichern. Zum Beispiel ist eine Zuordnung zu 97 und wenn wir diese Nummer speichern, ist es nur die Nummer und so ist Rune ein Alias für int32. Ist aber nicht irgendeine Zahl. Es ist eine Zahl mit 32 'Nullen und Einsen' oder '4' Bytes. (Hinweis: UTF-8 ist ein 4-Byte-Codierungsschema.)
Wie verhalten sich Runen zu Saiten?
Eine Zeichenfolge ist eine Sammlung von Runen. Im folgenden Code:
Wir versuchen, einen String in einen Bytestrom umzuwandeln. Die Ausgabe ist:
Wir können sehen, dass jedes der Bytes, aus denen diese Zeichenfolge besteht, eine Rune ist.
quelle
A string is not a collection of runes
Dies ist streng genommen nicht korrekt. Stattdessen ist string ein Byte-Slice, das mit utf8 codiert ist. Jedes Zeichen in einer Zeichenfolge benötigt tatsächlich 1 bis 3 Bytes, während jede Rune 4 Bytes benötigt. Sie können zwischen String und [] Rune konvertieren, aber sie sind unterschiedlich.Ich habe nicht genug Ruf, um einen Kommentar zur Antwort von fabrizioM zu schreiben , daher muss ich ihn stattdessen hier posten.
Fabrizios Antwort ist weitgehend richtig, und er hat sicherlich die Essenz des Problems erfasst - obwohl eine Unterscheidung getroffen werden muss.
Eine Zeichenfolge ist NICHT unbedingt eine Folge von Runen. Es ist ein Wrapper über einem 'Slice of Bytes', wobei ein Slice ein Wrapper über ein Go-Array ist. Welchen Unterschied macht das?
EIN Runentyp ist notwendigerweise ein 32-Bit-Wert, was bedeutet, dass eine Folge von Werten von Runentypen notwendigerweise eine bestimmte Anzahl von Bits x * 32 haben würde. Strings sind eine Folge von Bytes und haben stattdessen eine Länge von x * 8 Bits. Wenn alle Zeichenfolgen tatsächlich in Unicode wären, hätte dieser Unterschied keine Auswirkungen. Da Zeichenfolgen jedoch Slices von Bytes sind, kann Go ASCII oder eine beliebige andere Bytecodierung verwenden.
String-Literale müssen jedoch in die in UTF-8 codierte Quelle geschrieben werden.
Informationsquelle: http://blog.golang.org/strings
quelle
( Ich hatte das Gefühl, dass die obigen Antworten die Unterschiede und Beziehungen zwischen
string
und immer noch nicht[]rune
sehr deutlich darstellten, daher würde ich versuchen, eine weitere Antwort mit Beispiel hinzuzufügen.)Wie
@Strangework
die Antwort sagte,string
und[]rune
sind ganz anders.Unterschiede -
string
&[]rune
:string value
ist ein schreibgeschütztes Byte-Slice. Und ein Zeichenfolgenliteral ist in utf-8 codiert. Jedes Zeichen instring
tatsächlich nimmt 1 ~ 3 Bytes, während jederrune
dauert 4 Bytesstring
sowohllen()
als auch der Index basieren auf Bytes.[]rune
sowohllen()
als auch der Index basieren auf Rune (oder Int32).Beziehungen -
string
&[]rune
:string
nach konvertieren ,[]rune
wird jedes utf-8-Zeichen in dieser Zeichenfolge zu arune
.[]rune
nachstring
jedesrune
ein utf-8-Zeichen in derstring
.Tipps:
string
und konvertieren[]rune
, aber sie unterscheiden sich in Typ und Gesamtgröße.(Ich würde ein Beispiel hinzufügen, um dies deutlicher zu zeigen.)
Code
string_rune_compare.go:
Ausführen:
Ausgabe:
Erläuterung:
Die Zeichenfolge
hello你好
hat die Länge 11, da die ersten 5 Zeichen jeweils nur 1 Byte benötigen, während die letzten 2 chinesischen Zeichen jeweils 3 Byte benötigen.total bytes = 5 * 1 + 2 * 3 = 11
len()
on string auf Bytes basiert, wird somit die erste Zeile gedrucktlen: 11
uint8
(dabyte
es sich um einen Alias-Typ vonuint8
, in go handelt).Bei der Konvertierung
string
nach[]rune
wurden 7 utf8-Zeichen gefunden, also 7 Runen.len()
on[]rune
auf Rune basiert, wird somit die letzte Zeile gedrucktlen: 7
.[]rune
über Index arbeiten, greift es auf Basis der Rune zu.Da jede Rune von einem utf8-Zeichen in der ursprünglichen Zeichenfolge stammt, können Sie auch sagen, dass beide
len()
und[]rune
die Indexoperation auf utf8-Zeichen basieren.quelle
fmt.Println("hello你好"[0])
, wird der tatsächliche UTF-8-Codepunkt anstelle von Bytes zurückgegeben.s[0]
es druckts[0]: 104, type: uint8
, der Typ istuint8
, bedeutet , es ist ein Byte.h
Verwenden Sie für ASCII-Zeichen wie utf-8 auch ein einzelnes Byte, um es darzustellen, sodass der Codepunkt mit dem einzelnen Byte identisch ist. aber für chinesische Zeichen wie verwendet你
es 3 Bytes.Alle anderen haben den Teil im Zusammenhang mit Runen behandelt, deshalb werde ich nicht darüber sprechen.
Es gibt jedoch auch eine Frage, die sich darauf bezieht
switch
, keine Argumente zu haben. Dies liegt einfach daran, dass in Golangswitch
ohne Ausdruck eine alternative Möglichkeit ist, die if / else-Logik auszudrücken. Schreiben Sie zum Beispiel Folgendes:ist dasselbe wie dies zu schreiben:
Sie können mehr lesen hier .
quelle
Eine Rune ist ein int32-Wert und daher ein Go-Typ, der zur Darstellung eines Unicode-Codepunkts verwendet wird. Ein Unicode-Codepunkt oder eine Codeposition ist ein numerischer Wert, der normalerweise zur Darstellung einzelner Unicode-Zeichen verwendet wird.
quelle