Go 问答汇总(一)

最近比较忙,因为工作需要,必须快速了解一些新知识,写文少了,翻译多了。原因也很简单,翻译好文不仅可以帮助大家学习,自己也能学到更多。最近,还单独开了个专栏,用于保存自己翻译的计算机相关译文,大家如果有兴趣可以关注一下。Go 专栏或许当写到一定的程度时,更新频率会下降,但译文应该不会。

这周简单总结下近期在知乎上我的一些关于 Go 的问答。一方面是希望只关注专栏的朋友也能看到,毕竟不是所有内容都可以写出文章,另一方面,梳理一下也能方便以后自己查找。

Go 中没有 in,为什么会这样呢?其实还是因为它比较简单,实现起来也不是很复杂。回答中介绍了三种关于在 Go 中实现 in 的方式。

关于 Go 中大小端的问题,其实有专门的包处理这个问题,encoding/binary。回答中介绍了如何在 Go 中检查机器的大小端。还有,如何将 []byte 分别按大小端转化为 int 类型。

主要介绍了切片的底层结构,数组是连续,因而数据肯定是连续的。回答通过具体的代码测试了下 slice 是如何扩容的。

在调试接口的时候,经常遇到 \uxxxx 之类的字符串,为什么需要这样做呢?回答中说了一点个人的理解,\uxxxx 本质是 ascii 码,可以不用在意客户端的编码。但是这种方式,在我理解,也存在缺点,回答有所介绍。

题主要求挺高,要求从源码上去回答这个问题。为什么在发生数据竞争时,是 fatal error,而不是 panic。如果从设计上说,发生数据竞争是个比较严重的错误,会直接影响程序的执行结果,需要直接退出,而 panic 还是可以 recover 的,而这种错误还是不要 recover 比较好。当然,从源码层面,

对于传统面向对象语言的开发者,对于 Go 接口还是难以理解。最需要强调的一点,就是要先理解鸭子模型,基于此,再来理解为什么说 Go 接口是一组方法的集合,Go 接口是一种非侵入式的设计。

关于第二个问题,确切的说,就是题主还没有正确的理解 Go 的接口,简单地利用以往经验来理解 Go,理解 Go 的继承。从某种意义上说,Go 没有语法层面的继承,要实现继承的效果,需要通过组合实现。

当别人问到 Go 相对 C 最重要的改进是什么的时候,我优先想到并不是 Go 的并发模型,而是接口。经过前面两个问题,也会发现 Go 的接口的有点。它让我们的编码变的非常灵活。

关于 Go 的错误处理,这是个容易产生争论的问题,回答中我也只是引用了别人的言论,通过和传统的 try-catch 模型对比,我觉得也是一种更好的认识 Go 错误处理的一种方式。虽说,别人的说法不可全然接收,但多听听也总是好的。

最近,读了不好关于 Go 错误处理的文章,果断时间翻译几篇出来。除此以外,希望能在系统写一篇关于 Go 错误处理的文章。

这个问题我的确想了很久,slice 能重用内存是很好理解的,但是一直没想明白,为什么 Add 函数那么写就实现了重用内存。在回答了题主的问题后,顺便简单比较了下 Go 中 map 和 slice 的区别,随便扯的,应该是不够系统的。

在使用 Go 并发模型时,大家经常会认为 Go 的并发主要在函数前面加个 go 关键字就能加快效率。初期,我在学习的时候,也存在这个问题。本篇文章的题主也存在这个问题。

不知道有多数人都认为,只要在 Go 使用并发模型就可以实现高性能了。题主也存在这个问题,没有并发场景,只有一个 IO 的情况,强行使用 Go 的并发以求提高性能,这是完全不可能的。

我猜测,题主没有达到理想的效果,便认为 Go 中还有其他的并发方法来解决这个问题。看这个问题建议先具体看下问题描述。

问题大概是说 net/http 服务端的 req body 两次读取的第一次读取否需要立刻 close,回答中有个 stackoverflow 要求立刻关闭。而题主的问题是,为什么需要立刻关闭?

这个问题,只能通过阅读源码解决,因为我搜了半天的资料都没有找到答案。这个回答有些曲折。最终结论是,题主的问题已经不是问题,因为这是只有 Go 1.5 以及之前的版本才存在的问题。

想了解的朋友自行阅读回答。

暂时就梳理这么多,如果发现还有其他的问答没有汇总,会继续补充进来。


欢迎关注我的微信公众号。