That's because you used Scanner.Scan()
to read a rune
but it does something else. Scanner.Scan()
can be used to read tokens or rune
s of special tokens controlled by the Scanner.Mode
bitmask, and it returns special constants form the text/scanner
package, not the read rune itself.
To read a single rune
use Scanner.Next()
instead:
c := b.Next()
fmt.Println(c, string(c), strconv.QuoteRune(c))
Output:
97 a 'a'
If you just want to convert a single rune
to string
, use a simple type conversion. rune
is alias for int32
, and converting integer numbers to string
:
Converting a signed or unsigned integer value to a string type yields a string containing the UTF-8 representation of the integer.
So:
r := rune('a')
fmt.Println(r, string(r))
Outputs:
97 a
Also to loop over the runes of a string
value, you can simply use the for ... range
construct:
for i, r := range "abc" {
fmt.Printf("%d - %c (%v)
", i, r, r)
}
Output:
0 - a (97)
1 - b (98)
2 - c (99)
Or you can simply convert a string
value to []rune
:
fmt.Println([]rune("abc")) // Output: [97 98 99]
There is also utf8.DecodeRuneInString()
.
Try the examples on the Go Playground.
Note:
Your original code (using Scanner.Scan()
) works like this:
- You called
Scanner.Init()
which sets the Mode (b.Mode
) to scanner.GoTokens
.
-
Calling Scanner.Scan()
on the input (from "a"
) returns scanner.Ident
because "a"
is a valid Go identifier:
c := b.Scan()
if c == scanner.Ident {
fmt.Println("Identifier:", b.TokenText())
}
// Output: "Identifier: a"