個人Go之路

全職寫Go已經不少年了,我對於Go的認識,大概經歷過三次升級,但每一次突破,都不是Go語言自己帶來的,而是從其它語言領悟的,可見「功夫在詩外」。我想和你談談,這三次升級的關鍵的概念,它們是:接口,併發,反射。沒有一個概念是輕易理解的,就當你當初寫程序沒法一會兒理解變量同樣,它們更甚。編程

第一次是當年移動開發熱潮,我跟風買了Macbook Pro,裝Xcode,寫Objective-C。OC的做者Brad Cox原來寫Smalltalk,所以在C上面加了大量的宏,讓C支持面向對象。OC支持接口的方式是提供protocol。json

我對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的宏是一種元編程,能夠說是最強大的元編程形態,代碼即數據。ide

就像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也是多範式語言,博採衆長。

相關文章
相關標籤/搜索