Co to jest rune
w Go?
Googlowałem, ale Golang mówi tylko w jednym wierszu: rune
to pseudonimint32
.
Ale w jaki sposób liczby całkowite są używane dookoła, jak zamiana przypadków?
Poniżej wymieniono funkcję wymiany. Co to wszystko <=
i -
?
A dlaczego nie switch
ma żadnych argumentów?
&&
powinno znaczyć i co to jest 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
}
}
Większość z nich pochodzi z http://play.golang.org/p/H6wjLZj6lW
func SwapCase(str string) string {
return strings.Map(SwapRune, str)
}
Rozumiem, że to jest mapowanie, rune
aby string
mogło zwrócić zamieniony ciąg. Ale nie rozumiem, jak dokładnie rune
lub byte
tutaj działa.
[]rune
Można ustawić w logicznym, cyfry lub typu string. Zobacz stackoverflow.com/a/62739051/12817546 .Odpowiedzi:
Dosłowne oznaczenia run to tylko 32-bitowe wartości całkowite ( jednak są to stałe bez typu, więc ich typ może się zmienić ). Reprezentują punkty kodowe Unicode. Na przykład dosłowny znak runiczny
'a'
jest w rzeczywistości liczbą97
.Dlatego twój program jest prawie równoważny z:
Powinno być oczywiste, jeśli spojrzysz na mapowanie Unicode, które jest identyczne z ASCII w tym zakresie. Co więcej, 32 jest w rzeczywistości przesunięciem między wielkimi i małymi literami znaku. Więc dodając
32
do'A'
, dostajesz'a'
i na odwrót.źródło
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 }
Informacje o wydaniu Go lang: http://golang.org/doc/go1#rune
Runa jest typem. Zajmuje 32 bity i ma reprezentować Unicode CodePoint . Analogicznie zestaw angielskich znaków zakodowanych w „ASCII” ma 128 punktów kodowych. Dzięki temu może zmieścić się w bajcie (8 bitów). Z tego (błędnego) założenia C traktował znaki jako „bajty”
char
, a „łańcuchy” jako „sekwencję znaków”char*
.Ale zgadnij co. Istnieje wiele innych symboli wymyślonych przez ludzi innych niż symbole „abcde ..”. Jest ich tak wiele, że potrzebujemy 32 bitów, aby je zakodować.
W golang a
string
jest ciągiembytes
. Ponieważ jednak wiele bajtów może reprezentować runiczny punkt kodowy, wartość ciągu może również zawierać runy. Tak więc można go przekonwertować na a[]rune
lub odwrotnie.Pakiet Unicode http://golang.org/pkg/unicode/ może zasmakować bogactwa wyzwania.
źródło
rune
jest podobneint32
i ma wiele bitów.string
jest sekwencjąrune
s” - nie sądzę, że to prawda? Przejdź do blogu : „ciąg znaków to tylko kilka bajtów”; Go lang spec : „Wartość ciągu to (prawdopodobnie pusta) sekwencja bajtów”not bytes
. Następnie możesz powiedzieć: „Ciągi składają się z run, a runy składają się z bajtów” Coś w tym stylu. Potem znowu. to nie do końca prawda.Starałem się, aby mój język był prosty, aby laik zrozumiał
rune
.Runa jest postacią. Otóż to.
To jest jedna postać. To znak z dowolnego alfabetu z dowolnego języka z dowolnego miejsca na świecie.
Aby uzyskać ciąg, którego używamy
LUB
Sznurek jest inny niż runa. W runach używamy
Teraz runa jest także pseudonimem
int32
... Co?Powodem, dla którego runa jest aliasem,
int32
jest to, że widzimy to w schematach kodowania, takich jak poniżejkażda postać przypisana jest do pewnej liczby, a więc jest to liczba, którą przechowujemy. Na przykład, mapuje do 97 i kiedy zapisać ten numer to tylko liczba, a więc to sposób runa jest aliasem dla Int32. Ale to nie tylko liczba. Jest to liczba składająca się z 32 „zer i jedynek” lub „4” bajtów. (Uwaga: UTF-8 to 4-bajtowy schemat kodowania)
Jak runy odnoszą się do sznurków?
Ciąg to zbiór run. W następującym kodzie:
Próbujemy przekonwertować ciąg znaków na strumień bajtów. Dane wyjściowe to:
Widzimy, że każdy z bajtów tworzących ten ciąg jest runą.
źródło
A string is not a collection of runes
nie jest to ściśle ściśle mówiąc. Zamiast tego ciąg jest wycięciem bajtu, zakodowanym za pomocą utf8. Każdy znak w ciągu zajmuje w rzeczywistości 1 ~ 3 bajty, podczas gdy każda runa zajmuje 4 bajty. Możesz konwertować między runą a [] runą, ale są one różne.Nie mam wystarczającej reputacji, aby opublikować komentarz do odpowiedzi fabrizioM , więc będę musiał go tutaj zamieścić.
Odpowiedź Fabrizio jest w dużej mierze poprawna i na pewno uchwycił istotę problemu - choć należy wprowadzić rozróżnienie.
Ciąg jest nie koniecznie sekwencja run. Jest to opakowanie nad „plasterkiem bajtów”, przy czym plaster jest opakowaniem nad tablicą Go. Jaką to robi różnicę?
Runa typu jest oczywiście wartość 32 bitów, co oznacza sekwencję wartości run rodzaju musiałyby mieć pewną liczbę bitów X * 32. Łańcuchy będące sekwencją bajtów mają zamiast tego długość x * 8 bitów. Gdyby wszystkie łańcuchy były w rzeczywistości w Unicode, różnica nie miałaby wpływu. Ponieważ łańcuchy są kawałkami bajtów , Go może jednak używać ASCII lub dowolnego innego kodowania bajtów.
Jednak literały łańcuchowe muszą być zapisane w źródle zakodowanym w UTF-8.
Źródło informacji: http://blog.golang.org/strings
źródło
(Mam wrażenie, że powyższe odpowiedzi wciąż nie określały różnic i relacji między nimi,
string
i[]rune
bardzo wyraźnie, więc spróbuję dodać inną odpowiedź z przykładem).Jak
@Strangework
powiedziała odpowiedź,string
i[]rune
są cicho inni.Różnice -
string
i[]rune
:string value
jest bajtem tylko do odczytu. I literał łańcuchowy jest zakodowany w utf-8. Każdy znak wstring
rzeczywistości zajmuje 1 ~ 3 bajty, podczas gdy każdyrune
zajmuje 4 bajtystring
obulen()
indeks i są oparte na bajtach.[]rune
zarównolen()
indeks jak i oparte są na runie (lub int32).Relacje -
string
i[]rune
:string
na[]rune
, każdy znak utf-8 w tym ciągu staje sięrune
.[]rune
nastring
, każdyrune
staje się znakiem utf-8 w plikustring
.Wskazówki:
string
i[]rune
, ale nadal są one różne, zarówno pod względem typu, jak i ogólnego rozmiaru.(Dodałbym przykład, aby pokazać to jaśniej).
Kod
string_rune_compare.go:
Wykonać:
Wynik:
Wyjaśnienie:
Ciąg
hello你好
ma długość 11, ponieważ każde pierwsze 5 znaków zajmuje tylko 1 bajt, a ostatnie 2 znaki chińskie - 3 bajty.total bytes = 5 * 1 + 2 * 3 = 11
len()
ciąg jest oparty na bajtach, więc drukowany jest pierwszy wierszlen: 11
uint8
(ponieważbyte
jest to alias typuuint8
, in go).Kiedy przekonwertować
string
do[]rune
, stwierdzono 7 znaków utf8, a więc 7 run.len()
on[]rune
opiera się na runie, więc drukowana jest ostatnia linialen: 7
.[]rune
za pomocą indeksu, będzie on miał dostęp do bazy na runie.Ponieważ każda runa pochodzi z znaku utf8 w oryginalnym łańcuchu, możesz więc powiedzieć, że oba
len()
operacje na indeksie[]rune
są oparte na znakach utf8.źródło
fmt.Println("hello你好"[0])
, zwraca rzeczywisty punkt kodowy UTF-8 zamiast bajtów.s[0]
, ponieważ drukujes[0]: 104, type: uint8
, typ jestuint8
, oznacza jego bajt. W przypadku znaków ASCII, takich jakh
utf-8, również reprezentują go jeden bajt, więc punkt kodowy jest taki sam jak pojedynczy bajt; ale w przypadku chińskich znaków你
używa 3 bajtów.Wszyscy inni opisali część związaną z runami, więc nie zamierzam o tym mówić.
Istnieje jednak pytanie związane z
switch
brakiem argumentów. Jest tak po prostu dlatego, że w Golangswitch
bez wyrażenia jest alternatywnym sposobem wyrażenia logiki if / else. Na przykład pisząc to:jest taki sam jak napisanie tego:
Możesz przeczytać więcej tutaj .
źródło
Runa jest wartością int32, a zatem jest to typ Go używany do reprezentowania punktu kodowego Unicode. Punkt kodowy lub pozycja kodu Unicode to wartość liczbowa, która jest zwykle używana do reprezentowania pojedynczych znaków Unicode;
źródło