(J'ai le sentiment que les réponses ci-dessus n'ont pas encore clairement indiqué les différences et les relations entre chaîne
et []rune
, donc j'essaierais d'ajouter une autre réponse avec un exemple.)
Comme l'a dit la réponse de @Strangework
, chaîne
et []rune
sont assez différents.
Differences - chaîne
& []rune
:
la valeur de la chaîne
est une tranche de bytes en lecture seule. Et, une littérale de chaîne est encodée en utf-8. Chaque caractère dans chaîne
prend en réalité 1 ~ 3 bytes, tandis que chaque rune
en prend 4
- Pour
chaîne
, à la fois len()
et l'index sont basés sur des bytes.
- Pour
[]rune
, à la fois len()
et l'index sont basés sur des runes (ou int32).
Relations - chaîne
& []rune
:
- Lorsque vous convertissez de
chaîne
à []rune
, chaque caractère utf-8 dans cette chaîne devient un rune
.
- De même, dans la conversion inverse, en convertissant de
[]rune
à chaîne
, chaque rune
devient un caractère utf-8 dans la chaîne
.
Conseils:
- Vous pouvez convertir entre
chaîne
et []rune
, mais ils restent différents, à la fois en type et en taille globale.
(Je ajouterais un exemple pour montrer cela de manière plus claire.)
Code
string_rune_compare.go:
// comparaison de chaîne et rune,
package main
import "fmt"
// comparaison de chaîne et rune,
func stringAndRuneCompare() {
// chaîne,
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 // dernier 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()
}
Exécution:
go run string_rune_compare.go
Sortie:
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
Explication:
-
La chaîne hello你好
a une longueur de 11, car les 5 premiers caractères ne prennent chacun qu'un seul byte, tandis que les 2 derniers caractères chinois en prennent chacun 3.
- Ainsi,
total bytes = 5 * 1 + 2 * 3 = 11
- Puisque
len()
sur une chaîne est basé sur des bytes, la première ligne affiche donc len: 11
- Puisque l'index sur une chaîne est également basé sur des bytes, les 2 lignes suivantes affichent des valeurs de type
uint8
(car byte
est un type alias de uint8
, en go).
-
Lors de la conversion de la chaîne
en []rune
, il a trouvé 7 caractères utf8, donc 7 runes.
- Puisque
len()
sur []rune
est basé sur des runes, la dernière ligne affiche donc len: 7
.
- Si vous manipulez
[]rune
via un index, cela se fera en se basant sur les runes.
Puisque chaque rune provient d'un caractère utf8 dans la chaîne d'origine, vous pouvez également dire que à la fois len()
et les opérations d'index sur []rune
sont basées sur les caractères utf8.