J'ai le code suivant, il est censé couler un rune
dans un string
et l'imprimer. Cependant, j'obtiens des caractères non définis lors de l'impression. Je n'arrive pas à comprendre où se trouve le bug:
package main
import (
"fmt"
"strconv"
"strings"
"text/scanner"
)
func main() {
var b scanner.Scanner
const a = `a`
b.Init(strings.NewReader(a))
c := b.Scan()
fmt.Println(strconv.QuoteRune(c))
}
C'est parce que vous avez utilisé Scanner.Scan()
pour lire un rune
mais il fait autre chose. Scanner.Scan()
peut être utilisé pour lire tokens ou rune
s de jetons spéciaux contrôlés par le masque de bits Scanner.Mode
, et il renvoie des constantes spéciales du text/scanner
package, pas la rune de lecture elle-même.
Pour lire un seul rune
utilisez plutôt Scanner.Next()
:
c := b.Next()
fmt.Println(c, string(c), strconv.QuoteRune(c))
Sortie:
97 a 'a'
Si vous voulez simplement convertir un seul rune
en string
, utilisez un type simple conversion . rune
est un alias pour int32
, et convertit les nombres entiers en string
:
La conversion d'une valeur entière signée ou non signée en un type de chaîne produit une chaîne contenant la représentation UTF-8 de l'entier.
Alors:
r := rune('a')
fmt.Println(r, string(r))
Les sorties:
97 a
De plus, pour parcourir les runes d'une valeur string
, vous pouvez simplement utiliser la construction for ... range
:
for i, r := range "abc" {
fmt.Printf("%d - %c (%v)\n", i, r, r)
}
Sortie:
0 - a (97)
1 - b (98)
2 - c (99)
Ou vous pouvez simplement convertir une valeur string
en []rune
:
fmt.Println([]rune("abc")) // Output: [97 98 99]
Il y a aussi utf8.DecodeRuneInString()
.
Essayez les exemples sur le Go Playground .
Remarque:
Votre code d'origine (en utilisant Scanner.Scan()
) fonctionne comme ceci:
Scanner.Init()
qui définit le mode (b.Mode
) Sur scanner.GoTokens
.L'appel de Scanner.Scan()
sur l'entrée (à partir de "a"
) Renvoie scanner.Ident
Car "a"
Est un identifiant Go valide:
c := b.Scan()
if c == scanner.Ident {
fmt.Println("Identifier:", b.TokenText())
}
// Output: "Identifier: a"
Je sais que je suis un peu en retard à la fête, mais voici une fonction [] rune to string:
func runesToString(runes []rune) (outString string) {
// don't need index so _
for _, v := range runes {
outString += string(v)
}
return
}
oui, il y a un retour nommé mais je pense que c'est correct dans ce cas car cela réduit le nombre de lignes et la fonction n'est que courte