重庆分公司,新征程启航

为企业提供网站建设、域名注册、服务器等服务

Golang.org/x库初探2——text库-创新互联

  Golang有一个很有意思的官方库,叫golang.org/x,x可能是extends,experimental,总之是一些在官方库中没有,但是又很有用的库。最近花点时间把这里有用的介绍一下。

专业领域包括成都网站建设、成都网站制作、商城建设、微信营销、系统平台开发, 与其他网站设计及系统开发公司不同,创新互联的整合解决方案结合了帮做网络品牌建设经验和互联网整合营销的理念,并将策略和执行紧密结合,为客户提供全网互联网整合方案。
  1. Golang.org/x库初探1——image库
  2. Golang.org/x库初探2——text库
  3. Golang.org/x库初探3——sync库

  text库主要提供strings库的一系列Unicode和国际化适配的替代升级方案。常用的库如下:

golang.org/x/text/language

language库定义了BCP 47的语言标签支持,这里的语言指的自然语言,英语,中文等。

所谓的BCP 47 就是zh-CN这种格式的前面是语言,后面是地域的标识符(地域可选)

language库定义了Match等操作,这样你可以用来匹配最佳的语言,常用的是http中,用户在头部通过Accept-Language标识了他希望使用的语言,这样我们在服务端可以和服务器支持的语言进行匹配,寻找最合适的语言。

这个库虽然介绍的功能主要是Match功能,但同时也是cases等其他库用于标识语言的基础库,所以第一个介绍这个库。当然如果我们要做一个国际化程序,也可以把国际化标识这块,也使用lanuage库作为通用标识,以增强兼容性和标准化。

golang.org/x/text/cases

cases库用于支持国家化的大小写转换,写法如下

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/number

number库主要定义了很多帮助格式化数字的帮助函数,这个应该我们用的多点,可用的东西包括格式化函数和选项两类,格式化函数包括:

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下还有很多内容,我个人觉得用处不大,就不细讲了,包括

  1. currency: 货币支持库
  2. date: 国际化日期相关库
  3. search:本地化搜索支持,西文中差异较多,中文少
  4. secure:特殊用处下的文字有效性判断
  5. runes,collate:utf-8相关库
  6. unicode: unicode相关库
  7. transform: 转换库,可配合unicode下的各种定义来做特殊字符移除等功能
  8. 其他的功能库:feature、width
  9. 更多的编码库,包括韩文、日文等

详细的可以看官方库介绍

总的我认为:

  1. 编码转换可以直接用encoding库
  2. 国际化用message库
  3. Upper、Lower、Title等转换看需要用cases库或者标准strings库
  4. number库的功能很强大,在金融等应用场景下用处多多。

你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧


名称栏目:Golang.org/x库初探2——text库-创新互联
文章链接:http://cqcxhl.cn/article/gsioe.html

其他资讯

在线咨询
服务热线
服务热线:028-86922220
TOP