我正在学习《Go 编程语言》这本书,当它介绍字符串时,它说 Go 使用 utf-8 编码系统,因此很容易检查一个字符串是否是另一个基本字符串的前缀/后缀。使用以下函数:
func HasPrefix(s, prefix string) bool {
return len(s) >= len(prefix) && s[:len(prefix)] == prefix
}
func HasSuffix(s, suffix string) bool {
return len(s) >= len(suffix) && s[len(s)-len(suffix):] == suffix
}
我想知道当使用上述函数检查前缀/后缀时,是否存在任何编码系统会失败?
一种会破坏的编码
HasSuffix
是Big5:(十六进制)40 到 7E(含)之间的字节可以是完整字符,也可以是双字节字符的第二个字节。即使两个字符串使用相同的字节顺序,带有字节顺序标记的 UTF-16 或 UTF-32 也会中断
HasSuffix
(因为 中的 BOMsuffix
通常与 中正确位置的任何内容都不对应),而如果 和 不使用相同的字节顺序,则会中断它们。(但这在实践中不是问题,因为字节顺序标记仅用于通信,而不会在语言中用于所有字符串的表示。)s
HasPrefix
HasSuffix
我没有读过你提到的那本书,但它可能考虑的是不需要特定编码的语言,这样这些函数就需要知道每个字符串的编码并处理它们没有相同编码的情况。
可以说,即使 UTF-8 也不具备上述属性,因为这些函数无法识别“带有尖音符的 e”(一个 Unicode 字符)与“e 后跟组合尖音符”(两个 Unicode 字符)是同一个真实字符。但这显然是一个更难的问题。
您可以将 UTF-8 视为字节、代码点或字符序列。许多字符可以以不同的方式书写为代码点序列。例如,字母 (字母 e) 后跟 (重音符号 '),看起来像 é。如果您查看字符,那么“e”不是“é”的前缀,即使 é 以代码点 e 开头。
使用可用的最高级别的功能;它很有可能能够正确处理所有事情并快速处理简单的情况。