重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
Golang有一个很有意思的官方库,叫golang.org/x,x可能是extends,experimental,总之是一些在官方库中没有,但是又很有用的库。最近花点时间把这里有用的介绍一下。
专业领域包括成都网站建设、成都网站制作、商城建设、微信营销、系统平台开发, 与其他网站设计及系统开发公司不同,创新互联的整合解决方案结合了帮做网络品牌建设经验和互联网整合营销的理念,并将策略和执行紧密结合,为客户提供全网互联网整合方案。text库主要提供strings库的一系列Unicode和国际化适配的替代升级方案。常用的库如下:
golang.org/x/text/languagelanguage库定义了BCP 47的语言标签支持,这里的语言指的自然语言,英语,中文等。
所谓的BCP 47 就是zh-CN这种格式的前面是语言,后面是地域的标识符(地域可选)
language库定义了Match等操作,这样你可以用来匹配最佳的语言,常用的是http中,用户在头部通过Accept-Language标识了他希望使用的语言,这样我们在服务端可以和服务器支持的语言进行匹配,寻找最合适的语言。
这个库虽然介绍的功能主要是Match功能,但同时也是cases等其他库用于标识语言的基础库,所以第一个介绍这个库。当然如果我们要做一个国际化程序,也可以把国际化标识这块,也使用lanuage库作为通用标识,以增强兼容性和标准化。
golang.org/x/text/casescases库用于支持国家化的大小写转换,写法如下
var case = cases.Title(language.English, cases.NoLower)
fmt.Print(case.String("beforeThis")) //BeforeThis
这里的Title就是一般的Title case的用法。Title函数支持传入附加Option,上面传入了NoLower参数,用于标识除了首字母之外,其他非小写字母不需要转化为小写。
相比于标准库,cases的具体效果还是有区别,比如 下面的测试例:
func TestCases(t *testing.T) {
var tested = "beforeThis"
fmt.Println("基础库Title:", strings.ToTitle(tested))
var case1 = cases.Title(language.English)
fmt.Println("不带Option的cases Title:", case1.String(tested))
var case2 = cases.Title(language.English, cases.NoLower)
fmt.Println("带Option的cases Title:", case2.String(tested))
}
输出如下:
基础库Title: BEFORETHIS
不带Option的cases Title: Beforethis
带Option的cases Title: BeforeThis
基础库的ToTitle做完全大写转换还是有问题的,cases库就正常一点,对首字母大写即可。
而ToLower和ToUpper表现一致。
而国际化方面,主要针对几种语言做了适应性处理,主要是西欧语言的差异,这里就不多讲了,需要的同学可以从Title函数点进去看代码,有详细的注释
titleInfos = []struct {
title mapFunc
lower mapFunc
titleSpan spanFunc
rewrite func(*context)
}{
{title, lower, isTitle, nil}, // und
{title, lower, isTitle, afnlRewrite}, // af
{aztrUpper(title), aztrLower, isTitle, nil}, // az
{title, lower, isTitle, nil}, // el
{ltUpper(title), ltLower, noSpan, nil}, // lt
{nlTitle, lower, nlTitleSpan, afnlRewrite}, // nl
{aztrUpper(title), aztrLower, isTitle, nil}, // tr
}
golang.org/x/text/numbernumber库主要定义了很多帮助格式化数字的帮助函数,这个应该我们用的多点,可用的东西包括格式化函数和选项两类,格式化函数包括:
Decimal | 格式化逗号分隔的整数,例如1,234,567这种 |
Engineering | 类科学计数法(但指数部分最多有三位),输出类似这样:12.345678 × 10⁶ |
PerMille | 直接转成千分比数字,例如120‰ |
Percent | 百分比 |
Scientific | 科学计数法,输出类似这样:1.2345678 × 10⁷ |
另外,提供了多个Option来自定义输出:
FormatWidth | 指定数字转换后的字符串宽度,例如 number.PerMille(0.12, number.FormatWidth(10))会输出 “ 120‰” |
IncrementString | 一种宽泛的四舍五入算法,例如 number.PerMille(0.16, number.IncrementString("0.3"))会输出0.3,number.PerMille(0.14, number.IncrementString("0.3"))会输出0.0 |
MaxFractionDigits | 大小数位数(四舍五入) |
MaxIntegerDigits | 大整数位数(直接裁剪多余部分) |
MinIntegerDigits | 最小整数位数(补零) |
MinFractionDigits | 最小小数位数(补零) |
NoSeparator | 不分组数字 |
Precision | 浮点数精度,负数为小数位数,正数为整数位数 |
总的用法就是和message包配合,像fmt一样使用,例如官方库的案例
func TestNumber(t *testing.T) {
p := message.NewPrinter(language.Chinese)
p.Printf("%v bottles.\n", number.Decimal(3321.96, number.Precision(2)))
}
其中第二行展示了格式化函数和选项的用法。
这个库我们基本可以在很多需要格式化数字的地方用到了,原来很多很复杂的自定义写法都可以用这个来处理,这个库还提供了从上述标准函数派生自定义的入口NewFormat,大家可以从库中查找使用。
golang.org/x/text/message上面说了message库提供了一个类似fmt的国际化解决方案,同时可以和number等配合,做更多的格式化以及本地化适应的功能。
但同时他还是一个可以用于多语言翻译的库,在提供国际化方面有很大用处。
例如我们有这么一个帮助:
func TestNumber(t *testing.T) {
pZh := message.NewPrinter(language.Make("zh"))
pEn := message.NewPrinter(language.Make("en"))
message.SetString(language.English, "您输入的%s不符合要求\n", "The input value %s is not legal")
pZh.Printf("您输入的%s不符合要求\n", "1234")
pEn.Printf("您输入的%s不符合要求\n", "1234")
}
=== RUN TestNumber
您输入的1234不符合要求
The input value 1234 is not legal--- PASS: TestNumber (0.00s)
PASS
可以发现,英文的Printer直接转成了英文打印。
但是注意,这个定义必须完全一致才生效,所以官方的例子如下:
message.SetString(language.Dutch, "You have chosen to play %m.", "U heeft ervoor gekozen om %m te spelen.")
message.SetString(language.Dutch, "basketball", "basketbal")
message.SetString(language.Dutch, "hockey", "ijshockey")
message.SetString(language.Dutch, "soccer", "voetbal")
message.SetString(language.BritishEnglish, "soccer", "football")
for _, sport := range []string{"soccer", "basketball", "hockey"} {
for _, lang := range []string{"en", "en-GB", "nl"} {
p := message.NewPrinter(language.Make(lang))
fmt.Printf("%-6s %s\n", lang, p.Sprintf("You have chosen to play %m.", sport))
}
fmt.Println()
}
他首先用了一个Sprintf来把预定义国家化字符串进行转换,再做的Printf。
这个例子里还有一点说明的是,他使用了一个"%m"来说明传入变量要取国际化值,如果改成%s则不转换。
同时,text库提供了一个可编译库gotext用于在代码中获得所有的字符串,用于简化国际化的工作。
golang.org/x/text/encoding这个库,估计中文环境就用的很多了,就是传说中的编码库,用来做UTF-8,GBK,BIG5转换的,而且他把编码转换的框架进行了标准化,可以做不同编码格式的转换,这样就不需要再去用iconv等麻烦的东西了。
例如encoding下面的简体中文库simplifiedchinese提供了GB18030和GBK两个编码类,两个类都可以使用NewEncoder或NewDecoder来初始化一个编码器或者解码器,例如下面的例子,打开一个utf-8的文件,并转成gbk的:
f, err := os.Open("utftext.txt")
if err == nil {
var out *os.File
out, err = os.Create("gbk.txt")
if err == nil {
//将utf的reader转成gbk的reader
r := simplifiedchinese.GBK.NewDecoder().Reader(f)
//进一步读取拷贝
io.Copy(out, r)
out.Close()
f.Close()
}
}
当然,NewDecoder().Transform()直接按byte数组转换也是可以的。
其他更多当然,text下还有很多内容,我个人觉得用处不大,就不细讲了,包括
详细的可以看官方库介绍
总的我认为:
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧