对于绝大多数刚学习 Go 语言不久的人来说,如果你问他应该如何忽略大小写判断两个字符串相等,他大有可能写出类似下面这样的代码:
a, b := "Abc", "abc"
fmt.Println(strings.ToLower(a) == strings.ToLower(b))
strings.ToUpper()strings.ToTitle()
但是有没有人会好奇:为什么 Go 语言没有直接提供一个忽略大小写的函数? 先问是不是,再问为什么。 Go 其实是有提供的,只是一开始,很少有人知道罢了。就算后来知道了,可能又忘记名字了。
fmt.Println(strings.EqualFold("Go", "go")) // true
Go 标准库官方解释:
EqualFold reports whether s and t, interpreted as UTF-8 strings, are equal under Unicode case-folding, which is a more general form of case-insensitivity.
EqualFold 基于 Unicode case-folding 判断两个 UTF-8 字符串是否相等。这是 大小写不敏感比较 的更通用形式。
题外话,Elasticsearch 中也有类似的名词。见:ASCII folding token filter。
所以 Fold 是个什么鬼?
Fold 全称 Case Folding,暂时不知道中文叫什么翻译,大小写折叠?其来源于:Unicode 规范化(Unicode Normalization)。 Case-folding 的提出是为了解决国际语言的大小写问题,而不止是英语(拉丁系,英语中也有少部分外来词是这样)。
résumé[a-z][A-Z]RéSUMéRÉSUMÉ
为什么 Go 语言引入如此专业的名词,而不直接用类似 "EqualNoCase()" 之类的更加通俗易懂的词语? 我不知道,大概是想让更多的人知道“标准”的存在,能更多地知道制定标准的人所作的工作。
学了 Go 语言之后再回去看 C 语言的字符串忽略大小写的比较:
if (strcmp(toupper(foo),toupper(bar))==0) { // a typical caseless comparison
// 或 strcasecmp 或 stricmp 之类
rune