Go 语言核心 36 讲
郝林
《Go 并发编程实战》作者,前轻松筹大数据负责人
78704 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 55 讲
Go 语言核心 36 讲
15
15
1.0x
00:00/00:00
登录|注册

36 | unicode与字符编码

到目前为止,我们已经一起陆陆续续地学完了 Go 语言中那些最重要也最有特色的概念、语法和编程方式。我对于它们非常喜爱,简直可以用如数家珍来形容了。
在开始今天的内容之前,我先来做一个简单的总结。

Go 语言经典知识总结

基于混合线程的并发编程模型自然不必多说。
数据类型方面有:
基于底层数组的切片;
用来传递数据的通道;
作为一等类型的函数;
可实现面向对象的结构体;
能无侵入实现的接口等。
语法方面有:
异步编程神器go语句;
函数的最后关卡defer语句;
可做类型判断的switch语句;
多通道操作利器select语句;
非常有特色的异常处理函数panicrecover
除了这些,我们还一起讨论了测试 Go 程序的主要方式。这涉及了 Go 语言自带的程序测试套件,相关的概念和工具包括:
独立的测试源码文件;
三种功用不同的测试函数;
专用的testing代码包;
功能强大的go test命令。
另外,就在前不久,我还为你深入讲解了 Go 语言提供的那些同步工具。它们也是 Go 语言并发编程工具箱中不可或缺的一部分。这包括了:
经典的互斥锁;
读写锁;
条件变量;
原子操作。
以及 Go 语言特有的一些数据类型,即:
单次执行小助手sync.Once
临时对象池sync.Pool
帮助我们实现多 goroutine 协作流程的sync.WaitGroupcontext.Context
一种高效的并发安全字典sync.Map
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结
仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《Go 语言核心 36 讲》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(35)

  • 最新
  • 精选
  • lesserror
    郝林老师,请问一下:“基于混合线程的并发编程模型”。这句话该怎么理解呢?

    作者回复: 这里所谓的混合线程就是:OS内核外的线程/协程 + OS内核里的系统线程。 它牵扯到了两个程序级别,一个是用户级,一个是内核级,所以也叫“混合”或“两级”的线程模型。从数量对应的角度讲,它也叫M:N的线程模型(M指核外线程数量,N指核内线程数量),即两者之间是动态匹配的。你想想看,goroutine和系统线程是不是动态匹配的。Go语言的并发模型中不止有混合线程,但底层是基于此的。 相对应的,Java用的是1:1的纯内核级线程模型,也就是说JVM中的一个线程就等同于内核中的一个系统线程,一一对应。 还有就是,Python的绿色线程,是M:1的纯用户级线程模型。同进程内的多个绿色线程实际上共用一个线程,它们并不是真的并发执行(共用一个线程不可能出现并发执行的情况),只是通过调度看起来像并发执行而已。

    5
  • 小虾米
    这篇文章把unicode和utf8区分的不是很清楚,正如上面有个网友说的rune切变16进制输出是字符的unicode的码点,而byte切片输出的才是utf8的编码

    作者回复: 这么说没错,不过rune在底层也是字节串。

    4
    5
  • 🐻
    + 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
  • Gryllus
    终于追上了进度

    作者回复: 🐂

    3
  • 安排
    一个unicode字符在内存中存的是码点的值还是utf8对应的编码值?

    作者回复: 内存里存的是 UTF-8 的编码值,会由 1~4 个字节组成。Unicode 代码点是 Unicode 标准中用来唯一标识字符的东西。

    2
    2
  • qiushye
    str := "Go 爱好者 "fmt.Printf("Th... 您在文章里举的这个例子在Go后面多加了空格,会让人误解成遍历字符串可以跳过空格,github代码里没问题。

    作者回复: 收到,谢谢。已经通知编辑修正了。

    2
    2
  • 文武木子
    十六进制四个数字不是一共占用32位吗,一个字节不是8位嘛,这样不是占用4个字节吗?求大神解答

    作者回复: 你想问什么?十六进制的一位相当于二进制的四位。

    2
    1
  • 一个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
  • Geek_479239
    谢谢老师,这篇很有收获

    作者回复: 不客气,加油!

  • William Ning
    打卡,一直不明白字符集unicode与字符编码utf-8以及其他的编码实现方式的区别,现在有些理解,但是还是需要理一理。

    作者回复: 你还可以看看这篇文章:https://mp.weixin.qq.com/s/syyKS7lztRGTu1t00YhoFA ,我的另一本书的免费章节。

收起评论
显示
设置
留言
35
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部