Golang 从符文转换为字符串

Golang converting from rune to string

我有以下代码,它应该将 rune 转换为 string 并打印出来。但是,打印时出现未定义的字符。我无法弄清楚错误在哪里:

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

那是因为你使用的是 Scanner.Scan() to read a rune but it does something else. Scanner.Scan() can be used to read tokens or runes of special tokens controlled by the Scanner.Mode bitmask, and it returns special constants form the text/scanner 包,而不是读取符文本身。

要阅读单个 rune,请改用 Scanner.Next()

c := b.Next()
fmt.Println(c, string(c), strconv.QuoteRune(c))

输出:

97 a 'a'

如果您只想将单个 rune 转换为 string,请使用简单类型 conversionruneint32 的别名,将整数转换为 string:

Converting a signed or unsigned integer value to a string type yields a string containing the UTF-8 representation of the integer.

所以:

r := rune('a')
fmt.Println(r, string(r))

输出:

97 a

同样要遍历 string 值的符文,您可以简单地使用 for ... range 结构:

for i, r := range "abc" {
    fmt.Printf("%d - %c (%v)\n", i, r, r)
}

输出:

0 - a (97)
1 - b (98)
2 - c (99)

或者您可以简单地将 string 值转换为 []rune:

fmt.Println([]rune("abc")) // Output: [97 98 99]

还有utf8.DecodeRuneInString().

尝试 Go Playground 上的示例。

注:

您的原始代码(使用 Scanner.Scan())是这样工作的:

  1. 您调用 Scanner.Init() 将模式 (b.Mode) 设置为 scanner.GoTokens
  2. 在输入上调用 Scanner.Scan()(来自 "a")returns scanner.Ident 因为 "a" 是一个有效的 Go 标识符:

    c := b.Scan()
    if c == scanner.Ident {
        fmt.Println("Identifier:", b.TokenText())
    }
    
    // Output: "Identifier: a"
    

我知道我参加派对有点晚了,但这里有一个 []符文转字符串函数:

func runesToString(runes []rune) (outString string) {
    // don't need index so _
    for _, v := range runes {
        outString += string(v)
    }
    return
}

是的,有一个命名的 return 但我认为在这种情况下没问题,因为它减少了行数并且功能很短

自从我来到这个搜索符文和字符串和字符的问题后,认为这可能对像我这样的新手有所帮助

// str := "aഐbc"
// testString(str)
func testString(oneString string){

    //string to byte slice - No sweat -just type cast it
    // As string  IS A byte slice
    var twoByteArr []byte = []byte(oneString)

    // string to rune Slices - No sweat 
    // string IS A slice of runes 
    var threeRuneSlice []rune = []rune(oneString)

   // Hmm! String seems to have a dual personality it is both a slice of bytes and
   // a slice of runes - yeah - read on
    
    // A rune slice can be convered to string -
    // No sweat - as string == rune slice
    var thrirdString string = string(threeRuneSlice)
    
    // There is a catch here and that is in printing "characters", using for loop and range 
    
    fmt.Println("Chars in oneString")
    for i,r := range oneString {
        fmt.Printf(" %d  %v  %c ",i,r,r) //you may not get index 0,1,2,3 here  
        // since the range runs specially over strings  https://blog.golang.org/strings
    }
    
    fmt.Println("\nChars in threeRuneSlice")
    for i,r := range threeRuneSlice {
        fmt.Printf(" %d  %v  %c ",i,r,r) // i = 0,1,2,4 , perfect!!
        // as runes are made up of 4 bytes (rune is int32 and byte in unint8
        // and a set of bytes is used to represent a rune which is used to 
       // represent  UTF characters == the REAL CHARECTER 
    }

    fmt.Println("\nValues in oneString ")
    for j := 0; j < len(oneString); j++ {
        fmt.Printf(" %d %v ",j,oneString[j]) // No you cannot get charecters if you iterate through string in this way
        // as you are going over bytes here - not runes
    }
    fmt.Println("\nValues in twoByteArr")
    for j := 0; j < len(twoByteArr); j++ {
        fmt.Printf(" %d=%v ",j,twoByteArr[j]) // == same as above
    }
    
    fmt.Printf("\none - %s, two %s, three %s\n",oneString,twoByteArr,thrirdString)
}

还有一些毫无意义的演示https://play.golang.org/p/tagRBVG8k7V 改编自 https://groups.google.com/g/golang-nuts/c/84GCvDBhpbg/m/Tt6089MPFQAJ

显示 'characters' 根据 unicode 代码点编码为 1 到最多 4 个字节

这个简单的代码可以将符文转换为字符串

s := fmt.Sprintf("%c", rune)