文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Golang中Unicode与UTF-8有什么区别

2024-04-02 19:55

关注

Golang中Unicode与UTF-8有什么区别,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。

Unicode 与 UTF-8 编码

下面的图来自 UTF-8 的截图:

Golang中Unicode与UTF-8有什么区别

这幅图简单明了的告诉我们,UTF-8 的编码方式,比如汉字一般用三个 Byte,每个 Byte 的开头都是固定的,各种文字软件解析 UTF-8  编码的时候,它就会按照这个格式去解析,一旦解析错误(毕竟还可能会有不符合要求的数据,或者是文件错误了),错误的字节就会被替换为 “�”  (U+FFFD),然后神奇的地方就来了: 即使遇到这种错误,它也不会影响接下来的其他字符的解析 ,因为这种编码不必从头开始,使得它可以  自我同步(Self-synchronizing) 。与此同时,其它的一些编码一旦遇到错误编码就会出问题,导致错误编码之后的正确编码也会跟着出错。

当然,UTF-8 编码也有缺点,由于它是可变的,当英文字符偏多的时候,它会省空间,然而比如当中文偏多的时候,它理论上(3 Byte)会比 GBK 编码(2  Byte)最多多出 1/3 的存储空间。

UTF-8 的例子

我们拿 Unicode 中最受欢迎的 Emoji 表情 :joy: 1 来举例:它的 Code point 是 U+1F602 (对, 1F602 是以  16 进制表示的),然而在内存中它的存储方式的却是 0xf09f9882 ,为什么?这就是 UTF-8 的编码了(注意对比上图的编码方式):

000    011111    011000    000010 1f602 11110000  10011111  10011000  10000010 f0 9f 98 82

通过把 UTF-8 的编码格子里面数据提取出来,我们就能获得 Code point 1F602 。

你也可以用 Golang 来查看其它字符的编码:

package main import (    "fmt"     "unicode/utf8" )func main() {     fmt.Printf("%b\n", []byte(`:joy:`))     fmt.Printf("% x\n", []byte(`:joy:`))         r, _ := utf8.DecodeRuneInString(`:joy:`)     fmt.Printf("% b\n", r)     fmt.Printf("% x\n", r) }

Unicode 的其他编码

Unicode 当然不止一种编码,还有 UTF-16、UTF-32 等,它们的关系就是 UTF-16 用 2 个 Byte 来表示 UTF-8 分别用  1/2/3 个 Byte 来表示的字符,然后 4 个 Byte 与 UTF-8 一致,UTF-32 是完全用 4 个 Byte  来表示所有的字符,另外,详细的可以在 Comparison of Unicode encodings 中看到,

好,基础讲完,现在开始正式介绍。

Unicode 与 Golang 2

这里特别需要提到的是 Golang 与 UTF-8 的关系,他们背后的男人,都是 Ken Thompson 跟 Rob Pike 3 4 5  ,由此,大家就会明白 Golang 的 UTF-8 设计是有多么重要的参考意义。比如 Golang 设计了一个 rune 类型来取代 Code point  的意义。

rune 看源码就知道,它就是 int32,刚好 4 个 Byte,刚可以用来表示 Unicode 的所有编码 UTF-8 与 UTF-16。

在继续之前,我想帮各位明白一个事实:Golang 的源码是默认 UTF-8  编码的,这点从上面我给出的例子中就能明白,所以表情字符在编译的时候,就已经能被解析。

好了,那么我们来看看 Golang 的 unicode 包,其中就会有很多有用的判断函数:

func IsControl(r rune) bool func IsDigit(r rune) bool func IsGraphic(r rune) bool func IsLetter(r rune) bool func IsLower(r rune) bool func IsMark(r rune) bool func IsNumber(r rune) bool func IsPrint(r rune) bool func IsPunct(r rune) bool func IsSpace(r rune) bool func IsSymbol(r rune) bool func IsTitle(r rune) bool func IsUpper(r rune) bool

另外,在 src/unicode/tables.go 中,有大量的 Unicode 中,各类字符的 Code point  区间,会有比较大的参考价值。

再看看 unicode/utf8 包,这里面的函数,大多数时候你都用不到,但是有这么几类情况就需要你必须得用到了:

后面两个可以忽略,第一个需要特地提醒下:

s := `:joy:` fmt.Println(len(s))

这句输出是什么?上面提过了,刚好就是 4。于是,你不能使用 len  来获取字符数量,也就不能以此来判断用户输入的字符是不是超过了系统的限制。另外,你也不能通过 s[0] 这样的方式来获取字符,因为这样你只能取到这 4 个  Byte 中的第一个,也就是 0xf0 。

你应该做的就是把 string 转为 rune 数组,然后再去进行字符的操作。

具体的使用方法就不细谈了,相信你们能搞定。

另外,这里需要另外提示下,在 Node.js 中,string 本身就是 Unicode,而不是像 Golang 的 string  是二进制,因此在这里可以认为 Node.js 的 Buffer 才是 Golang 中的 string。

看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注编程网行业资讯频道,感谢您对编程网的支持。

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯