小编典典

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

go

存在无效的字节序列,无法将其转换为Unicode字符串。在Go中转换时如何检测[]bytestring


阅读 232

收藏
2020-07-02

共1个答案

小编典典

正如Tim
Cooper所述,您可以使用来测试UTF-8的有效性utf8.Valid

但!您可能会认为将非UTF-8字节转换为Go
string是不可能的。实际上,“在Go中,字符串实际上是只读的字节片段”;它可能包含无效的UTF-8字节,您可以打印这些字节,通过索引访问,甚至往返返回到[]byteWrite例如)。

Go在您的语言中有两个地方可以对进行UTF-8解码string

  • 当您执行操作时for i, r := range sr将Unicode代码点作为类型的值rune
  • 进行转换时[]rune(s),Go会将整个字符串解码为符文。

(请注意,这rune是的别名int32,而不是完全不同的类型。)

在这两种情况下,无效的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)
}

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

�
65533
[65533]
2020-07-02