编程我的上一篇文章,“我们不需要字符串类型”,导致了一点搅拌。虽然反馈混合了,但是字符串的常见主题是有用的特征。在进行更多的研究之后,我只能确定一件事:大多数当前的字符串类型被打破!
我们中的许多人认为我们的琴弦能够超过他们实际所做的事情。我们依靠他们的功能而实际检查它有效。这很容易导致不正常工作的程序,特别是在国际化方面。在大多数情况下,在没有字符串类型的情况下似乎我们会更好。
我看着字符串如何在一些基本情况下表现。我会跨越每种情况,给出预期的结果和一些实际结果。我考虑用结果显示一个矩阵,但由于所有测试语言表现得这么难,它似乎并不有用。
使用文本“noël”与分解的Unicode字符串“Noe \ U0308L”,我选中了以下内容:
1.它是否正确打印?是的,大多数语言都能够这样做。虽然IdeOne.com接口似乎打破了输出(所以要小心测试)。
2.逆转是什么? “lëon”,正确吗?大多数情况下都失败了。最常见的结果是“L̈eon”(分流者在'L'而不是'E'上)。这是在没有字符串类的情况下发生的事情,只需反转代码数组即可。
3.前三个字符是什么?主要是这里的答案是“noe”,而不是所需的“noë”。这很容易导致关于一个角色的大讨论,但我假设大多数人对当前结果不满意。这再次指示一个字符串类型,它仅将数据视为代码点数。
4.什么是长度?常见答案是5.又一次,这表明我们的字符串类型仅仅是字符数组,而不是真正处理文本。
对于所有这些问题,如果您在您喜欢的单词处理器或文本编辑器中编辑此文本,请尝试考虑应发生的情况。我通常希望“ë”字符作为一个实体处理。我不希望回溯/删除只能删除一部分字母。我希望复制前三个字母来包括重音。
unicode有一个猫咪有点奇怪(我希望你有一个字体,它显示它们 - 如果没有,这部分的标题是一个快乐的猫和一个悲伤的猫,unicode表情符号集的一部分)。选择这些字符,因为它们在BMP之外(基本的多语言平面)。使用UTF-16编码(Java,C#,JavaScript),这对语言的麻烦拼写。
1.长度? Python Unicode正确报告2.那些UTF-16语言倾向于报告4:字符需要代理对。
2.第一个角色后的子字符串? Python Unicode正确地报告了悲伤的猫“😾”。 UTF-16语言的弦线与半代理后跟悲伤的猫产生无效字符串。
逆转? Python Unicode获取“😾😸”的正确相反。 UTF-16语言产生无效字符串。用C#我认为我发现了意外的缺陷。它甚至没有显示无效的字符串,然后为整个程序显示任何输出! [太太缺陷]
语言使用编码不可知论图库,如C ++,Perl和普通Python 2字符串,在此处失败。它们忽略任何编码并假设字符串是一个1字节代码点的数组。 Python 3采用Unicode作为默认字符串类型,从而修复了一些问题。看来Perl也有一个'UTF8'模式,它修复了这些猫的问题,但不适用于“noël”字符串。
此字符串包含一个致字符,“ffl”部分是单个Unicode代码点。它们主要存在于兼容性,但它们是案例转换的良好测试。
1.什么是大写?我没有找到任何不打印“BA FFL E”的语言。请注意,结扎仍然是小写的。预期答案当然是“挡板”。
Unicode有一个特殊的案例转换:这个单一的拼字点实际转换为三个代码点。通过不遵循这些附加规则,语言大写函数会产生一个有趣的结果:转换为大写的字符串仍然存在小写字符。
最后检查我确实是将两个逻辑上等效的字符串与不同的组成形式进行比较。这里“noël”正在使用预先编译的“ë”字符。
1.预混==分解?答案在所有测试中都没有。但是,几种语言可以提供Unicode标准化库。在那些语言中,字符串的正常形式确实比较相等。 JavaScript没有这样的库,这是真正悲惨的,因为它主要是一种UI语言,究竟究竟想要正确的Unicode功能。
争论标准化和词汇分析不是基本字符串类型的一部分。但这些似乎是基本操作,一个人想做文字。如果不包括在内,则字符串类型的目的究竟是什么?
我鼓励您以您喜欢的语言运行此类测试。如果您正在与国际文本一起工作,您可以了解您的“字符串”类型实际执行的事项至关重要。一旦您运行此操作,您应该重新考虑您的“字符串”类型实际为您提供的操作。在我看来,他们都被打破了。
我承认正确的答案并不总是明确。 文本处理是一个困难的主题,并且在最小的最小范围内,我们必须覆盖图形群集(一些字符串类公开了与此相关的功能,并且Perl甚至具有GCString类)。 这超出了本文的范围,但与良好的字符串类型非常相关。 我在前一篇文章中提出的点变得更加尖锐。 我宁愿有一个字符数组而不是一个破碎的字符串类。 我没有对一系列字符进行虚假期望:它为上述测试产生的结果非常逻辑。 实际上,一系列Unicode字符在这些测试中比许多专用字符串类更好地执行更好。