web-dev-qa-db-fra.com

Golang conversion de rune en chaîne

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))
}
22
user3551708

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 runes 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:

  1. Vous avez appelé Scanner.Init() qui définit le mode (b.Mode) Sur scanner.GoTokens.
  2. 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"
    
18
icza

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

2
MarkJL