大家好,我是炸鱼。最近看Go1.18ReleaseNotes的时候,发现stringsandbytes标准库的Title方法已经弃用(Deprecated)了。为什么?今天的文章就由炸鱼和大家一起阅读。简介这里以字符串标准库为例。strings.Title方法的作用是将所有单词开头的Unicode字母映射到它们的Unicode标题大小写。示例如下:import("fmt""strings")funcmain(){fmt.Println(strings.Title("殿下"))fmt.Println(strings.Title("eddycjy"))fmt.Println(strings.Title("хлеб"))}输出结果:HerRoyalHighnessEddyCjyХлеб这些单词被转换为大写。问题看起来一切正常,但实际上他现阶段有2个明显的缺陷。分别为:Unicode标点符号无法正确处理。不考虑特定人类语言的大写规则。接下来,我们详细说说。第一个Unicode标点问题,例子如下:import("fmt""strings")funcmain(){a:=strings.Title("go.go\u2024go")b:="Go.Go\u2024Go"ifa!=b{fmt.Printf("%s!=%s\n",a,b)}}输出结果:Go.Go?go!=Go.Go?Go变量a的转换过程结果为“Go.Go?go”,但根据实际需要,应该为“Go.Go?Go”。第二题具体语言规则,代码如下:funcmain(){fmt.Println(strings.Title("ijsland"))}输出结果:Ijsland在荷兰语中,“ijsland”要大写为“IJsland",但结果被转换为"Ijsland"。解决方案这个问题是2013年发现的,来自《strings: Title function incorrectly handles word breaks》,被Go语言之父RobPike认定为计划外问题。如下图所示:由于Go1兼容性保证协议,这是“无法”修复的。一旦修复,将影响函数的输出,属于破坏性改变。但也可以通过另一种方式来实现,就是本文所说的“弃用”。标记如下://Title返回字符串s的副本,其中包含以单词开头的所有Unicode字母//映射到它们的Unicode标题大小写。////BUG(rsc):Title用于单词边界的规则不处理Unicode标点符号正确。////Deprecated:Usegolang.org/x/text/casesinstead.funcTitle(sstring)string{Identify"Deprecated"onthefunction:相应的Go文档将折叠它并清楚地显示deprecated,它推荐直接使用golang.org/x/text/cases库来实现这个功能。新的x/text/cases如下:import("fmt""golang.org/x/text/cases""golang.org/x/text/language")funcmain(){src:=[]string{“helloworld!”,“iwithdot”,“'nijsberg”,“O'Brian来了”,}for_,c:=range[]cases.Caser{cases.Lower(language.Und)案例Println(c.String(s))}}}输出:helloworld!iwithdot'nijsbergherecomeso'brianHELLOWORLD!?W?THDOT'N?JSBERGHERECOMESO'BR?ANHelloWorld!IWithDot'nIJsbergHereComesO'brianHelloWorld!IWithDot'NIjsbergHereComesO'Brian输出多种语言的转换。我们重点关注cases.Lower(language.Und)相关的代码,会调用:cases.Title(
