您的位置:首页 > 编程语言 > Go语言

在 Go 语言中处理 Unicode

2013-05-25 10:24 176 查看
如果‘Go’通常是指在公园散步,用Go语言处理Unicode码可以描述为不小心走进了雷区,比如,如果我们要获取从前端页面的一句简单字符串“Hello,世界”的长度.会得到什么结果?

1
fmt.Println(len(
"Hello,世界"
))
2
>>>13
等下,刚才发生了什么?长度难道不该是9么?其他额外的4个字符是从哪来的?在编译中,Go实际上把字符串编码为一个byte.go不像Python2.x一样让你区分普通ASCII码并反编码处理字符串,所以go还是不能从将中文字符编码为byte的实现中抽离出来,因为中文字符在ASCII表示中占用3byte而普通字符只占用1byte,所以Go告诉你长度是1*7+3*2=13.这对于那些想测试他们的ASCII字符串长度的人将是个令人迷惑的大水坑!看下面的例子

1
hello:=
"Hello,世界"
for
i:=rangehello{
2
fmt.Print(string(hello[i]))
3
}
4
>>>Hello,äç
出问题了,好吧,‘世界’怎么变成了‘äç’?也许我已经能听到你的咆哮了。。但是当你使用第二种range处理字符串,你确实可以这样处理

1
hello:=
"Hello,世界"
for
_,c:=rangehello{
2
fmt.Print(string(c))
3
}
4
>>>Hello,世界




BigOwen
翻译于昨天(10:25)

0人顶

顶翻译的不错哦!

结果好了很多!但我们确实不能这样做,为什么?用一个小例子,假设我们只是想用字符串中的每个字符与下个字符比较是否一样的.简单的处理方式可能是这样:

1
funcCompareChars(wordstring){
for
i,c:=rangeword{
if
i<len(word)-1{
2
fmt.Print(string(word[i+1])==string(c),
","
)
3
}
4
}
5
}
6
...
7
CompareChars(
"hello"
)
8
>>>
false
,
false
,
true
,
false
,
可是使用ASCII的字符串作为入参,结果实在是太烂了!如果我们使用中文说你好的话情况会是这样:

1
CompareChars(
"你好好好"
)
2
>>>
false
,
false
,
false
,
false
,
很明显这些字符串永远不会相等,因为我们总是用‘好’和好的第一byte的ASCII码‘\xE5’比较。

那么该怎么办?如果我们探索的够深,就会发现go排除了unicode/utf8的引用包,这个包不提供特别多功能,但是却能是我们解决遇到的第一个问题,查询‘hello’字符串的长度:

1
import(
"fmt"
"unicode/utf8"
)...fmt.Println(utf8.RuneCountInString(
"Hello,世界"
))
2
>>>9




BigOwen
翻译于昨天(11:17)

0人顶

顶翻译的不错哦!

好了,我们一开始期望的长度出现了。现在来升级一下我们先用到的CompareChars函数,使它能比较Unicode编码。

1
funcCompareChars(wordstring){s:=[]byte(word)
for
utf8.RuneCount(s)>1{r,size:=utf8.DecodeRune(s)s=s[size:]nextR,size:=utf8.DecodeRune(s)fmt.Print(r==nextR,
","
)}}
2
...CompareChars(
"hello"
)
3
>>>
false
,
false
,
true
,
false
,CompareChars(
"你好好好"
)
4
>>>
false
,
true
,
true
,
起作用了!
这个故事的寓意:工作时要非常小心,尤其是当与循环中的Unicode遍历字符串。最重要的是,在适当的情况下,使用内置的UTF-8封装,并牢记写测试要包含Unicode和ASCII字符串,。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: