如何检测Go中的字节何时无法转换为字符串?

cod*_*efx 6 string unicode encoding utf-8 go

无效的字节序列无法转换为Unicode字符串.转换[]bytestringGo 时如何检测?

two*_*two 13

正如Tim Cooper所说,你可以测试UTF-8的有效性utf8.Valid.

但!您可能认为将非UTF-8字节转换为Go string是不可能的.实际上,"在Go中,字符串实际上是一个只读字节片段" ; 它可以包含无效的UTF-8字节,您可以打印,通过索引访问,甚至往返往[]byte(Write比如说).

Go中有两个地方可以string为你做UTF-8解码.

  • 当你这样做时for i, r := range s,rUnicode代码点是一个类型的值rune
  • 当你进行转换时[]rune(s),Go会将整个字符串解码为符文

在这两种情况下,无效的UTF-8都替换U+FFFD替换字符,为此类用途保留.有关s和其他类型之间for语句转换string的规范部分中有更多内容.这些转换永远不会崩溃,因此您只需要主动检查UTF-8的有效性,如果它与您的应用程序相关,就像您想要在错误编码的输入上抛出错误一样.

由于这种行为已经融入了语言,因此您也可以从库中获得它.U+FFFDutf8.RuneError由函数返回utf8.

这是一个示例程序,显示Go对[]byte保持无效的UTF-8的作用:

package main

import "fmt"

func main() {
    a := []byte{0xff}
    s := string(a)
    fmt.Println(s)
    for _, r := range s {
        fmt.Println(r)
    }
    rs := []rune(s)
    fmt.Println(rs)
}
Run Code Online (Sandbox Code Playgroud)

在不同的环境中输出看起来会有所不同,但在Playground看起来很像

?
65533
[65533]
Run Code Online (Sandbox Code Playgroud)