Golang 15 : Les chaînes de caractères
Les chaînes de caractères
C'est quoi une chaîne de caractères?
Une chaîne de caractères en Go est une tranche de bits. Les chaîne de caractères peuvent être créés en enfermant leurs contenus dans " ".
Exemple:
package main
import (
"fmt"
)
func main() {
name := "Hello World"
fmt.Println(name)
}
La sortie du programme serait Hello World
.
Les strings en Go sont conformes à Unicode et sont encodés en UTF-8.
L'accès à un bit individuel d'un string
Une chaîne de caractères est une tranche de bits, c'est la raison pour laquelle il est possible d'accéder à chaque bit de la chaîne de caractères.
package main
import (
"fmt"
)
func printBytes(s string) {
for i:= 0; i < len(s); i++ {
fmt.Printf("%x ", s[i])
}
}
func main() {
name := "Hello World"
printBytes(name)
}
len(s) retourne le nombre de bits d'une chaîne de caractères , on utilise une boucle for pour afficher les bits en notation hexadécimal . %x est l'identificateur de format pour le hexadécimal. La sortie du programme ci-dessus est 48 65 6c 6c 6f 20 57 6f 72 6c 64
. Ce sont les valeurs encodées en Unicode UT8 de "Hello World".
On va modifier le programme ci-dessus pour afficher les caractères de la chaîne de caractères.
package main
import (
"fmt"
)
func printBytes(s string) {
for i:= 0; i < len(s); i++ {
fmt.Printf("%x ", s[i])
}
}
func printChars(s string) {
for i:= 0; i < len(s); i++ {
fmt.Printf("%c ",s[i])
}
}
func main() {
name := "Hello World"
printBytes(name)
fmt.Printf("\n")
printChars(name)
}
Dans la méthode printChars
, l' identificateur de format %c est utilisé pour afficher les caractères d'une chaîne de caractère . La sortie du programme serait:
48 65 6c 6c 6f 20 57 6f 72 6c 64
H e l l o W o r l d
Le programme ci-dessus a un sérieux bug, on va décomposer le code pour pouvoir savoir la source de ce bug.
package main
import (
"fmt"
)
func printBytes(s string) {
for i:= 0; i < len(s); i++ {
fmt.Printf("%x ", s[i])
}
}
func printChars(s string) {
for i:= 0; i < len(s); i++ {
fmt.Printf("%c ",s[i])
}
}
func main() {
name := "Hello World"
printBytes(name)
fmt.Printf("\n")
printChars(name)
fmt.Printf("\n")
name = "Señor"
printBytes(name)
fmt.Printf("\n")
printChars(name)
}
La sortie du programme est:
48 65 6c 6c 6f 20 57 6f 72 6c 64
H e l l o W o r l d
53 65 c3 b1 6f 72
S e à ± o r
Dans le programme ci-dessus, on a essayé d'afficher les caractères de Señor ce qui n'est pas affiché après l'exécution du programme, la raison de cette erreur est que le Unicode code point de** ñ** est U+00F1
et son encodage UTF-8 occupe 2 bits c3 et b1. On est entrain d'afficher des caractères en supposant que chaque point de code est de longueur un bit ce qui est faux. L'encodage d'un point de code en UTF-8 peut occuper plus qu'un seul bit. Pour résoudre cela, on a recours à rune.
rune
rune est un built-in type en go, c'est l'alias de int32. rune représente un Unicode code point en Go. Ie nombre de bits qu'un point de code occupe n'est pas important, il peut être représenté pas rune. On va modifier le programme ci-dessus pour afficher les caractères en utilisant rune.
package main
import (
"fmt"
)
func printBytes(s string) {
for i:= 0; i < len(s); i++ {
fmt.Printf("%x ", s[i])
}
}
func printChars(s string) {
runes := []rune(s)
for i:= 0; i < len(runes); i++ {
fmt.Printf("%c ",runes[i])
}
}
func main() {
name := "Hello World"
printBytes(name)
fmt.Printf("\n")
printChars(name)
fmt.Printf("\n\n")
name = "Señor"
printBytes(name)
fmt.Printf("\n")
printChars(name)
}
Dans le programme ci-dessus, la une chaîne de caractère est convertie en tranches de rune.
48 65 6c 6c 6f 20 57 6f 72 6c 64
H e l l o W o r l d
53 65 c3 b1 6f 72
S e ñ o r
la boucle for range
Go offre une méthode plus facile pour itérer sur les runes individuelles d'une chaîne de caractères en utilisant la boucle for range.
package main
import (
"fmt"
)
func printCharsAndBytes(s string) {
for index, rune := range s {
fmt.Printf("%c starts at byte %d\n", rune, index)
}
}
func main() {
name := "Señor"
printCharsAndBytes(name)
}
Voici la sortie du programme:
S starts at byte 0
e starts at byte 1
ñ starts at byte 2
o starts at byte 4
r starts at byte 5
Construction d'une une chaîne de caractère à partir d'une tranche de bits
package main
import (
"fmt"
)
func main() {
byteSlice := []byte{0x43, 0x61, 0x66, 0xC3, 0xA9}
str := string(byteSlice)
fmt.Println(str)
}
Dans le programme ci-dessus, runeSlice
contient les points de code Unicode de la chaîne de caractères Señor
en héxadécimal. Le programme affiche Señor
.
Longueur d'une chaîne de caractères
La fonction func RuneCountInString(s string) (n int)
de utf8 package est utilisée pour trouver la longueur d'une chaîne de caractères.
package main
import (
"fmt"
"unicode/utf8"
)
func length(s string) {
fmt.Printf("longueur est %s est %d\n", s, utf8.RuneCountInString(s))
}
func main() {
word1 := "Señor"
length(word1)
word2 := "Pets"
length(word2)
}
La sortie du programme ci-dessus est:
longueur de Señor est 5
longueur de Pets est 4
Les chaînes de caractères sont immuables
package main
import (
"fmt"
)
func mutate(s string)string {
s[0] = 'a'//tout caractère unicode valide qui se trouve entre ' ' est une rune
return s
}
func main() {
h := "hello"
fmt.Println(mutate(h))
}
Dans le programme ci-dessus, on a essayeé de changer le premier caractère de la chaîne de caractères en 'a'
. Cela n'est pas possible car Les chaînes de caractères sont immuables, par conséquent, le programme lance une erreur main.go:8: cannot assign to s[0].
package main
import (
"fmt"
)
func mutate(s []rune) string {
s[0] = 'a'
return string(s)
}
func main() {
h := "hello"
fmt.Println(mutate([]rune(h)))
}
Dans le programme ci-dessus, la fonction mutate
a comme argument une tranche de rune t. Le premier élément de la tranche est changé en 'a', puis la rune est reconvertie en chaîne de caractères et retournée. h
est converti en tranche de runes et puis passé à mutate
. Le programme affiche aello
.
Posted on Utopian.io - Rewarding Open Source Contributors
Thank you for the contribution. It has been approved.
You can contact us on Discord.
[utopian-moderator]
Hey @raptorjesus I am @utopian-io. I have just upvoted you!
Achievements
Suggestions
Get Noticed!
Community-Driven Witness!
I am the first and only Steem Community-Driven Witness. Participate on Discord. Lets GROW TOGETHER!
Up-vote this comment to grow my power and help Open Source contributions like this one. Want to chat? Join me on Discord https://discord.gg/Pc8HG9x