关于golang:Go118-新特性弃用-stringsTitle-方法换个新坑吧

40次阅读

共计 2348 个字符,预计需要花费 6 分钟才能阅读完成。

大家好,我是煎鱼。

最近在看 Go1.18 Release Notes 时,发现 strings, bytes 规范库的 Title 办法,居然被弃用了(Deprecated),这是为什么呢?

明天这篇文章就由煎鱼和大家一起看看。

介绍

这里以 strings 规范库为例,strings.Title 办法的作用是:将所有单词结尾的 Unicode 字母映射到其 Unicode 题目大小写。

例子如下:

import (
    "fmt"
    "strings"
)

func main() {fmt.Println(strings.Title("her royal highness"))
    fmt.Println(strings.Title("eddy cjy"))
    fmt.Println(strings.Title("хлеб"))
}

输入后果:

Her Royal Highness
Eddy Cjy
Хлеб

这些单词均被转换为其大写。

问题

看上去仿佛所有都很美妙,但其实他现阶段有 2 个显著的缺点。

别离是:

  • 无奈正确处理 Unicode 标点符号。
  • 不思考特定人类语言的大写规定。

接下来咱们具体开展讲讲。

Unicode 标点符号

第一个问题,例子如下:

import (
    "fmt"
    "strings"
)

func main() {a := strings.Title("go.go\u2024go")
    b := "Go.Go\u2024Go"
    if a != b {fmt.Printf("%s != %s\n", a, b)
    }
}

输入后果:

Go.Go․go != Go.Go․Go

变量 a 转换解决的后果是“Go.Go․go”,但依照理论的诉求该当为“Go.Go․Go”。

特定语言规定

第二个问题,代码如下:

func main() {fmt.Println(strings.Title("ijsland"))
}

输入后果:

Ijsland

在荷兰语的单词中,“ijsland”应大写为“IJsland”,但后果转换为“Ijsland”。

解决方案

这个问题在 2013 年就发现了,来源于《strings: Title function incorrectly handles word breaks》,被 Go 语言之父 Rob Pike 标识为计划外的问题。

如下图:

因为 Go1 兼容性保障的公约,因而这是“无奈”修复的,一旦修复就会影响函数的输入后果,是破坏性变更。

但也能够采取别的形式,也就是本文中提到的“弃用”。如下标识:

// Title returns a copy of the string s with all Unicode letters that begin words
// mapped to their Unicode title case.
//
// BUG(rsc): The rule Title uses for word boundaries does not handle Unicode punctuation properly.
//
// Deprecated: Use golang.org/x/text/cases instead.
func Title(s string) string {

在函数上标识“Deprecated”:

对应 Go 文档会将其折叠并明确显示弃用,倡议间接应用 golang.org/x/text/cases 库来实现该性能。

新的 x/text/cases 案例如下:

import (
    "fmt"

    "golang.org/x/text/cases"
    "golang.org/x/text/language"
)

func main() {src := []string{
        "hello world!",
        "i with dot",
        "'n ijsberg",
        "here comes O'Brian",
    }
    for _, c := range []cases.Caser{cases.Lower(language.Und),
        cases.Upper(language.Turkish),
        cases.Title(language.Dutch),
        cases.Title(language.Und, cases.NoLower),
    } {fmt.Println()
        for _, s := range src {fmt.Println(c.String(s))
        }
    }
}

输入后果:

hello world!
i with dot
'n ijsberg
here comes o'brian

HELLO WORLD!
İ WİTH DOT
'N İJSBERG
HERE COMES O'BRİAN

Hello World!
I With Dot
'n IJsberg
Here Comes O'brian

Hello World!
I With Dot
'N Ijsberg
Here Comes O'Brian

输入了多种语言的转换,咱们外围关注 cases.Lower(language.Und) 相干的代码,该库会通过调用:

  • cases.Title(<language>).Bytes(<bytes>)
  • cases.Title(<language>).String(<string>)

在编程中指定解决的语言,来解决不同人类语言的符号、不同语言和大写词语的诉求,防止一刀切。

总结

尽管只有一个小小的函数,但也延长出了不少的问题。实质上还是在设计时,存在认知的局限性。

另外 strings.Titlebytes.Title 函数,在理论工作中也常被误会为就是转换首字母大写的办法,与设计含意相违反。

尽管最终与缺点相比,这样的误会却带来了更好的成果,但对于一些非凡场景和语言反对,还是有很大的问题。

也算是塞翁失马,焉知非福了。

若有任何疑难欢送评论区反馈和交换,最好的关系是相互成就 ,各位的 点赞 就是煎鱼创作的最大能源,感激反对。

文章继续更新,能够微信搜【脑子进煎鱼了】浏览,本文 GitHub github.com/eddycjy/blog 已收录,学习 Go 语言能够看 Go 学习地图和路线,欢送 Star 催更。

正文完
 0