您可能想为此使用strings.ToValidUTF8():
ToValidUTF8 返回字符串 s 的副本,其中每次运行无效的 UTF-8 字节序列都被替换字符串替换,该替换字符串可能为空。
它“看似”完全符合您的需要。测试它:
a := []byte{'a', 0xff, 0xaf, 'b', 0xbf}
s := strings.ToValidUTF8(string(a), ".")
fmt.Println(s)
输出(在Go Playground上试试):
a.b.
我写“貌似”是因为如您所见,a 和 b 之间只有一个点:因为可能有 2 个字节,但有一个无效序列。
请注意,您可能会避免使用 []byte => string 转换,因为有一个 bytes.ToValidUTF8() 等价物可以操作并返回 []byte:
a := []byte{'a', 0xff, 0xaf, 'b', 0xbf}
a = bytes.ToValidUTF8(a, []byte{'.'})
fmt.Println(string(a))
输出将是相同的。在Go Playground 上试试这个。
如果您对多个(无效序列)字节可能会缩小为一个点感到困扰,请继续阅读。
还要注意,要检查可能包含或不包含文本的任意字节切片,您可以简单地使用hex.Dump(),它会生成如下输出:
a := []byte{'a', 0xff, 0xaf, 'b', 0xbf}
fmt.Println(hex.Dump(a))
输出:
00000000 61 ff af 62 bf |a..b.|
这是您预期的输出 a..b. 以及其他(有用的)数据,例如十六进制偏移量和字节的十六进制表示。
要获得“更好”的输出图片,请尝试使用更长的输入:
a = []byte{'a', 0xff, 0xaf, 'b', 0xbf, 50: 0xff}
fmt.Println(hex.Dump(a))
00000000 61 ff af 62 bf 00 00 00 00 00 00 00 00 00 00 00 |a..b............|
00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000030 00 00 ff |...|
在Go Playground 上试试。