摘要:在函數式編程的特性支持上,Erlang作爲函數式語言,支持最爲全面。而且從筆者的併發編程體驗上看,Erlang的函數式編程語法風格和其OTP behavior框架提供的晦澀的回調(callback)使用方法,對大部分的程序員,如C/C++和Java出身的程序員來說,有一定的入門門檻和挑戰。

因爲Go的語法和Erlang、Python類似,所以我們將這三門語言做個詳細的對比。

相比於Python的40個特性,Go只有31個,可以說Go在語言設計上是相當剋制的。比如,它沒有隱式的數值轉換,沒有構造函數和析構函數,沒有運算符重載,沒有默認參數,也沒有繼承,沒有泛型,沒有異常,沒有宏,沒有函數修飾,更沒有線程局部存儲。

但是Go的特點也很鮮明,比如,它擁有協程、自動垃圾回收、包管理系統、一等公民的函數、棧空間管理等。

Go作爲靜態類型語言,保證了Go在運行效率、內存用量、類型安全都要強於Python和Erlang。

Go的數據類型也更加豐富,除了支持表、字典等複雜的數據結構,還支持指針和接口類型,這是Python和Erlang所沒有的。特別是接口類型特別強大,它提供了管理類型系統的手段。而指針類型提供了管理內存的手段,這讓Go進入底層軟件開發提供了強有力的支持。

Go在面對對象的特性支持上做了很多反思和取捨,它沒有類、虛函數、繼承、泛型等特性。Go語言中面向對象編程的核心是組合和方法(function)。組合很類似於C語言的struct結構體的組合方式,方法類似於Java的接口(Interface),但是使用方法上與對象更加解耦,減少了對對象內部的侵入。Erlang則不支持面對對象編程範式,相比而言,Python對面對對象範式的支持最爲全面。

在函數式編程的特性支持上,Erlang作爲函數式語言,支持最爲全面。但是基本的函數式語言特性,如lambda、高階函數、curry等,三種語言都支持。

控制流的特性支持上,三種語言都差不多。Erlang支持尾遞歸優化,這給它在函數式編程上帶來便利。而Go在通過動態擴展協程棧的方式來支持深度遞歸調用。Python則在深度遞歸調用上經常被爆棧。

Go和Erlang的併發模型都來源於CSP,但是Erlang是基於actor和消息傳遞(mailbox)的併發實現,Go是基於goroutine和管道(channel)的併發實現。不管Erlang的actor還是Go的goroutine,都滿足協程的特點:由編程語言實現和調度,切換在用戶態完成,創建銷燬開銷很小。至於Python,其多線程的切換和調度是基於操作系統實現,而且因爲GIL的大坑級存在,無法真正做到並行。

而且從筆者的併發編程體驗上看,Erlang的函數式編程語法風格和其OTP behavior框架提供的晦澀的回調(callback)使用方法,對大部分的程序員,如C/C++和Java出身的程序員來說,有一定的入門門檻和挑戰。而被稱爲“互聯網時代的C”的Go,其類C的語法和控制流,以及面對對象的編程範式,編程體驗則好很多。

相關文章