我的Go之路

从知乎上看来的一篇文章,感触很深,特意做一个记录。

全职写Go已经很多年了,我对于Go的认识,大概经历过三次升级,但每一次突破,都不是Go语言本身带来的,而是从其它语言领悟的,可见“功夫在诗外”。我想和你谈谈,这三次升级的关键的概念,它们是:接口,并发,反射。没有一个概念是轻易理解的,就像你当初写程序无法一下子理解变量一样,它们更甚。

第一次是当年移动开发热潮,我跟风买了Macbook Pro,装Xcode,写Objective-C。OC的作者Brad Cox原来写Smalltalk,因此在C上面加了大量的宏,让C支持面向对象。OC支持接口的方式是提供protocol。

我对iOS的框架UIKit中大量使用了delegate的设计方案印象深刻,尤其是UITableViewDelegate这个protocol,要完成一个TableView的操作,需要用户提供实现了这个接口的对象,这个对象可以是self,也可以其它对象,重点是要实现protocol定义的方法。我不知道多少人对self.delegate = self产生困惑。这种接口思想在Go标准库中,到外都有,io.Reader, io.Writer,json.Marshaler等等。可以说Go一定意义上是面向接口设计的语言。如果说面向对象设计的精髓是面向接口编程,那么Go便是。

另外Go的接口额外的两个特性是对象隐式实现接口,以及空接口作为一切类型的容器。隐式实现有点像动态语言的duck typing,如果对象没有实现接口定义的方法,那将无法通过编译。而空接口提供一定的泛型编程的能力,并且与反射息息相关。接口的概念很多语言都有,在Java中有大量的资料讲的是接口的设计,理解接口,设计能力会有极大提升。

第二次是对PHP并发的怨念促使我在Erlang中学习并发。Erlang是一门面向并发的编程语言,它强调一切都是进程,进程之间完全隔离,整个语言围绕着这个出发点而设计的;进程调度是完全公平的,不会因为某一个进程执行占用大量CPU而其它进程得不到CPU资源,它是并发的基础。

面向对象语言之父,同是也是Smalltalk之父,Alan Kay,解释面向对象时说道:“The big idea is messaging.", Erlang进程之间的通信就是靠发送消息,发送消息是异步的——发送方不必等待接收方收到消息才算发送完成,反而所谓面向对象语言的函数调用是同步的。Go的channel在有缓存并且没满的时候,发送方是异步的,当channel是无缓存或者缓存满了,发送方就是同步的,需要等待接收方取走消息之后,发送方才算完成。要理解messaging或者channel,把这个过程放大,看做发送方把消息发给消息队列,接收方监听消息队列。

Go的并发哲学是:“Do not communicate by sharing memory; instead, share memory by communicating.” Go提供了与Erlang相似的并发机制,同时也照顾传统并发编程的需求提供了sync包——传统加锁的并发方案。并发编程可以有效提升程序性能,掌握之后对程序的设计能力也有显著的提高。

第三次是在学习《SICP》,想到《黑客与画家》作者Paul Graham在《拒绝平庸》一文里说道:”有了Lisp语言的帮助,我们的开发周期很短。有时候,竞争对手刚刚发布新闻稿宣布将引入新功能,我们就能在一两天内做出自己的版本。”Lisp的宏是一种元编程,可以说是最强大的元编程形态,代码即数据。

就像Lisp解释器把代码当数据解析,Go的反射把类型当参数。Go官方《The Laws of Reflection》总结的反射三定律是基础,如何应用才是重点。反射处理对象是代码本身,不是直接的业务数据,所以相关处理代码十分晦涩;通常反射代码不应该存在于业务逻辑中,而存在于库与框架中。翻一下框架与库,发现满眼的reflect,这是Go丑陋的一面,但是不得不面对的一面。好处是reflect也是静态类型,不会像Lisp那样当人不在状态的时候根本无法阅读。使用Go的反射可以写出对使用者而言整洁的代码,不用像使用空接口那样做类型断言,但相对而言,要生成反射对象本身,增加了运行时开销。Go的设计初衷是快速编译,因此舍弃了对泛型的支持,Go的作者作出了取舍。

元编程是一个高阶话题,不易理解,但就像《Ruby元编程》作者说道:“哪里有元编程,都只是编程而已。”,把代码当成数据,你能做的超乎你的想像。如果你想要做得更多,Go也提供了go/types, go/ast等包用于解析Go源代码,你就能做代码生成了。

我对于以上的三个Go的特性,接口、并发、反射,就像理解任何知识一样,需要对比参照与旧知识发生关联,再加上大量的实践,才能有所体会。Go还有很多优秀的设计,比如defer,struct embed, first-class function等。Go的设计充满了权衡,对语言的特性的取舍更多关注的是软件工程领域,Go也是多范式语言,博采众长。

我为什么放弃go语言? 对于为什么放弃go语言,每个人的原因可能不尽相同。以下是我个人对放弃go语言的一些主要原因: 1. 生态系统相对较小:相较于其他主流编程语言,比如Java、Python和JavaScript,Go语言的生态系统相对较小。这意味着在使用Go语言开发项目时,可能需要自己编写很多常见功能的库,而不能直接从现有的包中获取。这对于开发速度和效率会有一些影响。 2. 编译速度较慢:与一些其他编程语言相比,Go语言的编译速度较慢。这对于频繁进行代码调试和测试的开发者来说可能是一个不小的问题,特别是在项目规模较大时。 3. 静态类型限制:尽管静态类型可以提供更高的代码安全性和执行效率,但相对于一些动态语言来说,Go语言的类型系统相对较为繁琐。这意味着相同的功能可能需要更多的代码来实现,也会增加开发时间和复杂度。 4. 缺乏一些常用工具和库:在某些领域,Go语言的生态系统相对较弱,缺乏一些常用的工具和库。这可能需要开发者自己去重复造轮子,不仅增加了开发成本,也可能导致项目质量和稳定性的问题。 总的来说,每个编程语言都有其优点和缺点,适用于不同的场景和需求。放弃一门编程语言通常是基于自身的需求和优先级而做出的决策。以上只是我个人对放弃go语言的一些理解和想法,可能并不适用于所有人。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值