Comparing Strings
我们之前已经看到, Go字符串支持比较操作符(<, <=, ==, !=, >, >=); 这此比较操作符是在内存中一个字节一个字节(byte)的进行比较. 但对于使用Unicode字符串的语言来讲,进行字符串的比较会有以下三个问题
第一个问题是有些Unicode字符可以由两个或者多个不同的字节(byte)序列构成. 比如字符Å可以是一个Ångström 符号或者是字母A跟一个圆环构成. 这两种表示的形式在视觉是一样的。 Ångström 符号的Unicode代码点是U+212B. 而A同小圆圈的代表点为U+00C5(Latin Capital Letter a with Ring Above) 或者由两个代码点U+0041(A) 和 U+030A(°)组成。 Ångström 符号的字节是[0xE2, 0x84, 0xAB], Å(U+00C5)字符的字节为[0xC3, 0x85], A 和 °的组合[0x41, 0xCC, 0x81]. 当然,从使用者的看到的角度来讲两个Å的比较应该是相等的。
对于第一个问题并不是非常严重,因为Go产生的UTF-8的字节(byte)序列都是使用相同的代码点(code point)到字节的映射。 这是什么意思呢? 举个例子, é字符在Go的字符或者stirng常量中都是使用相同的字节。同样,如果只关心ASCII字符,则根本不用半心这个问题。 甚至在处理非ASCII字符时,这个问题也仅仅出现在当两个字符看起来一样的时候。或者是当我们在读取程序之外的UTF-8字节时(被读取的文件的code point到 字节映射跟Go的映射不同). 如果真的出现这些问题,我们可以自定义一些标准化函数。举个例子, é通常由[0xC3, 0xA9]表示(Go的代码点映射到字节), 而不是由[0x65, 0xCC, 0x81] (e and ´ ). 关于标准化Unicode字符的解释可以查看(unicode.org/reports/tr15).
第二个问题是有此情况下用户希望不同的字符应该认为是相等的,比如一个程序提供了搜索的功能,它们希望"5"可以匹配"5","₅", "⑤". 对于这个跟第一个问题的处理一样,可以使用自定义的标准函数。
第三个问题是相同的字符在不同语言中的排序问题, 在英文中ø排到o的后面,而丹麦语和挪威语中它排在Z之后。