(J'ai le sentiment que les réponses ci-dessus n'indiquent toujours pas les différences et les relations entre string
et []rune
très clairement, alors j'essaierais d'ajouter une autre réponse avec un exemple.)
Comme @Strangework
l'a dit la réponse, string
et []rune
sont calmes différents.
Différences - string
& []rune
:
string value
est une tranche d'octets en lecture seule. Et, une chaîne littérale est codée en utf-8. Chaque caractère string
prend en fait 1 à 3 octets, tandis que chacun rune
prend 4 octets
- Pour
string
, les deux len()
et index sont basés sur des octets.
- Pour
[]rune
, les deux len()
et index sont basés sur rune (ou int32).
Relations - string
& []rune
:
- Lorsque vous convertissez de
string
en []rune
, chaque caractère utf-8 de cette chaîne devient un rune
.
- De même, dans la conversion inverse, lors de la conversion de
[]rune
en string
, chacun rune
devient un caractère utf-8 dans le fichier string
.
Conseils:
- Vous pouvez convertir entre
string
et []rune
, mais ils sont toujours différents, à la fois dans le type et la taille globale.
(J'ajouterais un exemple pour le montrer plus clairement.)
Code
string_rune_compare.go:
package main
import "fmt"
func stringAndRuneCompare() {
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
fmt.Printf("s[%d]: %v, type: %T\n\n", li, s[li], s[li])
rs := []rune(s)
fmt.Printf("%v, type: %T, len: %d\n", rs, rs, len(rs))
}
func main() {
stringAndRuneCompare()
}
Exécuter:
lancez string_rune_compare.go
Production:
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 prennent chacun 1 octet seulement, tandis que les 2 derniers caractères chinois prennent chacun 3 octets.
- Donc,
total bytes = 5 * 1 + 2 * 3 = 11
- Puisque la
len()
chaîne est basée sur des octets, la première ligne est donc impriméelen: 11
- Puisque l'index sur la chaîne est également basé sur des octets, les 2 lignes suivantes impriment des valeurs de type
uint8
(puisque byte
c'est un type d'alias de uint8
, in go).
Lors de la conversion du string
to []rune
, il a trouvé 7 caractères utf8, donc 7 runes.
- Puisque
len()
on []rune
est basé sur la rune, donc la dernière ligne est imprimée len: 7
.
- Si vous opérez
[]rune
via index, il accédera à la base sur la rune.
Étant donné que chaque rune provient d'un caractère utf8 dans la chaîne d'origine, vous pouvez donc également dire que les deux len()
et les opérations d'indexation []rune
sont basées sur les caractères utf8.