36 | unicode与字符编码
36 | unicode与字符编码
讲述:黄洲君
时长16:45大小5.76M
Go 语言经典知识总结
前导内容 1:Go 语言字符编码基础
前导内容 2: ASCII 编码
问题解析
知识扩展
总结
思考题
赞 20
提建议
精选留言(35)
- wade2018-11-07而后三个十六进制数7231、597d和8005都相对较大,它们分别表示中文字符'爱'、'好'和'者'。这些中文字符对应的 UTF-8 编码值,都需要使用三个字节来表达。所以,这三个数就是把对应的三个字节来表达。所以,这三个数就是把对应的三个字节的编码值,转换为整数后得到的结果。 "爱好者"对应的7231、597d、8005,不是UTF-8编码值,是unicode码点。unicode码点和最终计算器存储用的utf-8编码值不是一样的。转换成rune的时候rune切片每个元素存储一个unicode码点,也就是string里的一个字符转成rune切片的一个元素。string是以utf-8编码存储,byte切片也就是存储用的string用utf-8编码存储后的字节序。 unicode和utf-8的关系,可以看这个文章 http://www.ruanyifeng.com/blog/2007/10/ascii_unicode_and_utf-8.html展开共 5 条评论50
- ONLY2020-05-15unicode只是给全世界的字符做了一个编码,假如世界上有100亿个字符,那么从0到100亿,有的数只占用一个字节,有的数二个有的数三个…,找到对应的编号就找到了对应的字符。unicode只给字符分配了编号,没有说怎么去存储这些字符,用1字节存不下,100字节太浪费,于是utf-8就想到了一个存储的点子,因为生活中用到的字符用4个字节应该能存下了,于是就用1到4个字节来存储这些字符,占1个字节的就用1字节存储,2字节的就用2字节存储,以此类推……,utf8要做的就是怎么去判断一个字符到底用了几个字节存储,就好比买绳子一样,有的人要两米有的人要一米,不按照尺寸剪肯定不行,具体怎么减咱们先不关心这个留给utf8去处理。存储这些编码在计算机里就是二进制。这些二进制utf8能读懂,但是计算机看来就是01没啥了不起的,8二进制放到4字节存储没毛病吧,装不满的高位大不了填充0,就是这么有钱豆浆喝一杯倒一杯,这个就是[]rune, 但是世界总有吃不饱饭的人看着闹心,那还是一个字节一个字节存吧,等需要查看字符的时候大不了再转换为rune切片,这就是[]byte展开共 1 条评论20
- 冰激凌的眼泪2018-11-05src文件编码是utf8 string是utf8编码的mb,len(string)是字节的长度 string可以转化为[]rune,unicode码,32bit的数字,当字符看,len([]rune)为字符长度 string可以转化为[]byte,utf8编码字节串,len([]byte)和len(string)是一样的 for range的时候,迭代出首字节下标和rune,首字符下标可能跳跃(视上一个字符编码长度定)15
- 冰激凌的眼泪2018-11-02看rune大小 转成byte看长度 加个小尾巴,range看间隔9
- 小虾米2018-12-16这篇文章把unicode和utf8区分的不是很清楚,正如上面有个网友说的rune切变16进制输出是字符的unicode的码点,而byte切片输出的才是utf8的编码
作者回复: 这么说没错,不过rune在底层也是字节串。
共 4 条评论5 - lesserror2021-08-23郝林老师,请问一下:“基于混合线程的并发编程模型”。这句话该怎么理解呢?
作者回复: 这里所谓的混合线程就是:OS内核外的线程/协程 + OS内核里的系统线程。 它牵扯到了两个程序级别,一个是用户级,一个是内核级,所以也叫“混合”或“两级”的线程模型。从数量对应的角度讲,它也叫M:N的线程模型(M指核外线程数量,N指核内线程数量),即两者之间是动态匹配的。你想想看,goroutine和系统线程是不是动态匹配的。Go语言的并发模型中不止有混合线程,但底层是基于此的。 相对应的,Java用的是1:1的纯内核级线程模型,也就是说JVM中的一个线程就等同于内核中的一个系统线程,一一对应。 还有就是,Python的绿色线程,是M:1的纯用户级线程模型。同进程内的多个绿色线程实际上共用一个线程,它们并不是真的并发执行(共用一个线程不可能出现并发执行的情况),只是通过调度看起来像并发执行而已。
4 - 🐻2019-04-22+ isrunesingle.go ```go package show_rune_length func isSingleCharA(c rune) bool { return int32(c) < 128 } func isSingleCharB(c rune) bool { data := []byte(string(c)) return len(data) == 1 } func isSingleCharC(c rune) bool { data := string(c) + " " for i, _ := range data { if i == 0 { continue } if i == 1 { return true } else { return false } } return false } ``` + isrunesingle_test.go ```go package show_rune_length import ( "testing" "github.com/stretchr/testify/assert" ) type CharJudger func(c rune) bool func TestIsSingleChar(t *testing.T) { for _, judger := range []CharJudger{ isSingleCharA, isSingleCharB, isSingleCharC, } { assert.True(t, judger('A')) assert.True(t, judger(rune(' '))) assert.False(t, judger('😔')) assert.False(t, judger('爱')) } } ```展开
作者回复: 可以用 unicode/utf8 代码包中的 RuneCount 函数。
3 - 韡WEI2018-11-15rune怎么翻译?有道查的:神秘的记号。为什么这么命名这个类型?有没有什么故事?共 2 条评论3
- Gryllus2018-11-02终于追上了进度
作者回复: 🐂
3 - 安排2019-09-18一个unicode字符在内存中存的是码点的值还是utf8对应的编码值?
作者回复: 内存里存的是 UTF-8 的编码值,会由 1~4 个字节组成。Unicode 代码点是 Unicode 标准中用来唯一标识字符的东西。
共 2 条评论2 - qiushye2019-09-05str := "Go 爱好者 "fmt.Printf("Th... 您在文章里举的这个例子在Go后面多加了空格,会让人误解成遍历字符串可以跳过空格,github代码里没问题。
作者回复: 收到,谢谢。已经通知编辑修正了。
共 2 条评论2 - 趣学车2020-11-18len(s) == 1 则为单字节1
- 文武木子2019-10-10十六进制四个数字不是一共占用32位吗,一个字节不是8位嘛,这样不是占用4个字节吗?求大神解答
作者回复: 你想问什么?十六进制的一位相当于二进制的四位。
共 2 条评论1 - 党2019-07-30一个unicode字符点都是由两个字节存储,为什么在go语言中 type rune = int32 四个字节 而不是 type rune=16 两个字节啊
作者回复: Unicode 代码点是一个抽象的概念,并且没有规定占用的字节数,只是说以“U+XXXX”的形式来表示。“X”还可能有 5 个或 6 个。 Unicode 代码点是 Unicode 编码标准的一部分。但你要分清楚编码标准和编码格式(像 UTF-8、UTF-16 等等)的区别。前者是概念和表示法,后者是真正的落地格式。编码格式才是真正与存储占用(比如一个字符占用多少个字节)有关的东西。 rune 类型的宽度是 4 个字节,那是因为 Go 语言使用 UTF-8 编码格式。这种格式编出来的码最多占用 4 个字节。
1 - benying2019-06-13打卡,讲的挺清楚的,谢谢1
- 花见笑2022-09-19 来自广东UTF-8的编码规则: 1、对于单字节的字符,字节的第一位设为0,后面七位为这个字符的Unicode码。 因此对于英文字符,UTF-8编码和ASCII码是相同的。 2、对于n字节的字符(n>1),第一个字节的前n位都设为1,第n+1位设为0,后面字节的 前两位一律设为10。剩下的没有提及的二进制位,全部为这个字符的Unicode编码。 UTF-8每次传送8位数据,并且是一种可变长的编码格式 具体来说,是怎么的可变长呢. 分为四个区间: 0x0000 0000 至 0x0000 007F:0xxxxxxx 0x0000 0080 至 0x0000 07FF:110xxxxx 10xxxxxx 0x0000 0800 至 0x0000 FFFF:1110xxxx 10xxxxxx 10xxxxxx 0x0001 0000 至 0x0010 FFFF:11110xxx 10xxxxxx 10xxxxxx 10xxxxxx UTF-8解码过程: 对于采用UTF-8编码的任意字符B 如果B的第一位为0,则B为ASCII码,并且B独立的表示一个字符; 如果B的前两位为1,第三位为0,则B为一个非ASCII字符,该字符由多个字节表示, 并且该字符由两个字节表示; 如果B的前三位为1,第四位为0,则B为一个非ASCII字符,该字符由多个字节表示, 并且该字符由三个字节表示; 比如汉字 “王”,它的二进制形式为: 0x0000 738B,属于第三区间, 0x0000 738B - 00000000 00000000 01110011 10001011, 第三区间的编码是 1110xxxx 10xxxxxx 10xxxxxx 把x都给替换,则最终"王"字对应的Unicode的编码是 11100111 10001110 10001011 转换成16进制 0xe7 0x8e 0x8b 如果B的前四位为1,第五位为0,则B为一个非ASCII字符,该字符由多个字节表示, 并且该字符由四个字节表示;展开
- Geek_4792392022-04-20谢谢老师,这篇很有收获
作者回复: 不客气,加油!
- William Ning2022-02-18打卡,一直不明白字符集unicode与字符编码utf-8以及其他的编码实现方式的区别,现在有些理解,但是还是需要理一理。
作者回复: 你还可以看看这篇文章:https://mp.weixin.qq.com/s/syyKS7lztRGTu1t00YhoFA ,我的另一本书的免费章节。
- 窝窝头2022-02-15看它的长度或者转换类型判断
- Louhwz2021-04-06这章讲的很清楚,谢谢