(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 w string
rzeczywistości zajmuje 1 ~ 3 bajty, podczas gdy każdy rune
zajmuje 4 bajty
- Dla
string
obu len()
indeks i są oparte na bajtach.
- Bo
[]rune
zarówno len()
indeks jak i oparte są na runie (lub int32).
Relacje - string
i []rune
:
- Kiedy konwertujesz z
string
na []rune
, każdy znak utf-8 w tym ciągu staje się rune
.
- Podobnie, w konwersji odwrotnej, po konwersji z
[]rune
na string
, każdy rune
staje się znakiem utf-8 w pliku string
.
Wskazówki:
- Możesz konwertować między
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:
// string & rune compare,
package main
import "fmt"
// string & rune compare,
func stringAndRuneCompare() {
// string,
s := "hello你好"
fmt.Printf("%s, type: %T, len: %d\n", s, s, len(s))
fmt.Printf("s[%d]: %v, type: %T\n", 0, s[0], s[0])
li := len(s) - 1 // last index,
fmt.Printf("s[%d]: %v, type: %T\n\n", li, s[li], s[li])
// []rune
rs := []rune(s)
fmt.Printf("%v, type: %T, len: %d\n", rs, rs, len(rs))
}
func main() {
stringAndRuneCompare()
}
Wykonać:
idź uruchom string_rune_compare.go
Wynik:
hello你好, type: string, len: 11
s[0]: 104, type: uint8
s[10]: 189, type: uint8
[104 101 108 108 111 20320 22909], type: []int32, len: 7
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.
- A zatem,
total bytes = 5 * 1 + 2 * 3 = 11
- Ponieważ
len()
ciąg jest oparty na bajtach, więc drukowany jest pierwszy wierszlen: 11
- Ponieważ indeks na łańcuchu jest również oparty na bajtach, dlatego następujące 2 wiersze wypisują wartości typu
uint8
(ponieważ byte
jest to alias typu uint8
, in go).
Kiedy przekonwertować string
do []rune
, stwierdzono 7 znaków utf8, a więc 7 run.
- Ponieważ
len()
on []rune
opiera się na runie, więc drukowana jest ostatnia linia len: 7
.
- Jeśli operujesz
[]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.