(Ho avuto la sensazione che le risposte di cui sopra ancora non indicassero le differenze e le relazioni tra string
e []rune
molto chiaramente, quindi proverei ad aggiungere un'altra risposta con l'esempio.)
Come @Strangework
detto la risposta, string
e []rune
sono abbastanza diversi.
Differenze - string
& []rune
:
string value
è una porzione di byte di sola lettura. E, una stringa letterale è codificata in utf-8. Ogni char in string
effettivamente richiede 1 ~ 3 byte, mentre ciascuno rune
richiede 4 byte
- Per
string
, sia len()
e indice sono basati su byte.
- Per
[]rune
, sia len()
e indice sono basati su rune (o int32).
Relazioni - string
& []rune
:
- Quando converti da
string
in []rune
, ogni carattere utf-8 in quella stringa diventa a rune
.
- Allo stesso modo, nella conversione inversa, quando convertito da
[]rune
in string
, ognuno rune
diventa un carattere utf-8 in string
.
Suggerimenti:
- Puoi convertire tra
string
e []rune
, ma sono comunque diversi, sia per tipo che per dimensione complessiva.
(Vorrei aggiungere un esempio per mostrarlo più chiaramente.)
Codice
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()
}
Eseguire:
vai a eseguire string_rune_compare.go
Produzione:
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
Spiegazione:
La stringa hello你好
ha lunghezza 11, perché i primi 5 caratteri richiedono ciascuno solo 1 byte, mentre gli ultimi 2 caratteri cinesi richiedono ciascuno 3 byte.
- Così,
total bytes = 5 * 1 + 2 * 3 = 11
- Poiché
len()
on string si basa sui byte, viene quindi stampata la prima rigalen: 11
- Poiché anche l'indice su stringa si basa su byte, le seguenti 2 righe stampano valori di tipo
uint8
(poiché byte
è un tipo alias di uint8
, in go).
Quando ha convertito string
in []rune
, ha trovato 7 caratteri utf8, quindi 7 rune.
- Poiché
len()
su []rune
si basa sulla runa, quindi l'ultima riga stampata len: 7
.
- Se operi
[]rune
tramite indice, accederà alla base su una runa.
Poiché ogni runa proviene da un carattere utf8 nella stringa originale, quindi puoi anche dire che entrambe le len()
operazioni e l'indice su []rune
sono basate su caratteri utf8.