正如 “21 世紀(jì)的 C 語言” 這句話所說,Go 語言并不是憑空而造的,而是和 C++、Java 和 C# 一樣屬于 C 系。不僅如此,設(shè)計(jì)者們還汲取了其它編程語言的精粹部分融入到 Go 語言當(dāng)中。
在聲明和包的設(shè)計(jì)方面,Go 語言受到 Pascal、Modula 和 Oberon 系語言的影響;在并發(fā)原理的設(shè)計(jì)上,Go 語言從同樣受到 Tony Hoare 的 CSP(通信序列進(jìn)程 Communicating Squential Processes)理論影響的 Limbo 和 Newsqueak 的實(shí)踐中借鑒了一些經(jīng)驗(yàn),并使用了和 Erlang 類似的機(jī)制。
這是一門完全開源的編程語言,因?yàn)樗褂?BSD 授權(quán)許可,所以任何人都可以進(jìn)行商業(yè)軟件的開發(fā)而不需要支付任何費(fèi)用。
盡管為了能夠讓目前主流的開發(fā)者們能夠?qū)?Go 語言中的類 C 語言的語法感到非常親切而易于轉(zhuǎn)型,但是它在極大程度上簡(jiǎn)化了這些語法,使得它們比 C/C++ 的語法更加簡(jiǎn)潔和干凈。同時(shí),Go 語言也擁有一些動(dòng)態(tài)語言的特性,這使得使用 Python 和 Ruby 的開發(fā)者們?cè)谑褂?Go 語言的時(shí)候感覺非常容易上手。
下圖展示了一些其它編程語言對(duì) Go 語言的影響:
http://wiki.jikexueyuan.com/project/the-way-to-go/images/1.3.influences_on_go.jpg?raw=true" alt="" />
圖 1.3 其它編程語言對(duì) Go 語言的影響
Go 語言的主要目標(biāo)是將靜態(tài)語言的安全性和高效性與動(dòng)態(tài)語言的易開發(fā)性進(jìn)行有機(jī)結(jié)合,達(dá)到完美平衡,從而使編程變得更加有樂趣,而不是在艱難抉擇中痛苦前行。
因此,Go 語言是一門類型安全和內(nèi)存安全的編程語言。雖然 Go 語言中仍有指針的存在,但并不允許進(jìn)行指針運(yùn)算。
Go 語言的另一個(gè)目標(biāo)是對(duì)于網(wǎng)絡(luò)通信、并發(fā)和并行編程的極佳支持,從而更好地利用大量的分布式和多核的計(jì)算機(jī),這一點(diǎn)對(duì)于谷歌內(nèi)部的使用來說就非常重要了。設(shè)計(jì)者通過 goroutine 這種輕量級(jí)線程的概念來實(shí)現(xiàn)這個(gè)目標(biāo),然后通過 channel 來實(shí)現(xiàn)各個(gè) goroutine 之間的通信。他們實(shí)現(xiàn)了分段棧增長(zhǎng)和 goroutine 在線程基礎(chǔ)上多路復(fù)用技術(shù)的自動(dòng)化。
這個(gè)特性顯然是 Go 語言最強(qiáng)有力的部分,不僅支持了日益重要的多核與多處理器計(jì)算機(jī),也彌補(bǔ)了現(xiàn)存編程語言在這方面所存在的不足。
Go 語言中另一個(gè)非常重要的特性就是它的構(gòu)建速度(編譯和鏈接到機(jī)器代碼的速度),一般情況下構(gòu)建一個(gè)程序的時(shí)間只需要數(shù)百毫秒到幾秒。作為大量使用 C++ 來構(gòu)建基礎(chǔ)設(shè)施的谷歌來說,無疑從根本上擺脫了 C++ 在構(gòu)建速度上非常不理想的噩夢(mèng)。這不僅極大地提升了開發(fā)者的生產(chǎn)力,同時(shí)也使得軟件開發(fā)過程中的代碼測(cè)試環(huán)節(jié)更加緊湊,而不必浪費(fèi)大量的時(shí)間在等待程序的構(gòu)建上。
依賴管理是現(xiàn)今軟件開發(fā)的一個(gè)重要組成部分,但是 C 語言中“頭文件”的概念卻導(dǎo)致越來越多因?yàn)橐蕾囮P(guān)系而使得構(gòu)建一個(gè)大型的項(xiàng)目需要長(zhǎng)達(dá)幾個(gè)小時(shí)的時(shí)間。人們?cè)絹碓叫枰婚T具有嚴(yán)格的、簡(jiǎn)潔的依賴關(guān)系分析系統(tǒng)從而能夠快速編譯的編程語言。這正是 Go 語言采用包模型的根本原因,這個(gè)模型通過嚴(yán)格的依賴關(guān)系檢查機(jī)制來加快程序構(gòu)建的速度,提供了非常好的可量測(cè)性。
整個(gè) Go 語言標(biāo)準(zhǔn)庫的編譯時(shí)間一般都在 20 秒以內(nèi),其它的常規(guī)項(xiàng)目也只需要半秒鐘的時(shí)間來完成編譯工作。這種閃電般的編譯速度甚至比編譯 C 語言或者 Fortran 更加快,使得編譯這一環(huán)節(jié)不再成為在軟件開發(fā)中困擾開發(fā)人員的問題。在這之前,動(dòng)態(tài)語言將快速編譯作為自身的一大亮點(diǎn),像 C++ 那樣的靜態(tài)語言一般都有非常漫長(zhǎng)的編譯和鏈接工作。而同樣作為靜態(tài)語言的 Go 語言,通過自身優(yōu)良的構(gòu)建機(jī)制,成功地去除了這個(gè)弊端,使得程序的構(gòu)建過程變得微不足道,擁有了像腳本語言和動(dòng)態(tài)語言那樣的高效開發(fā)的能力。
另外,Go 語言在執(zhí)行速度方面也可以與 C/C++ 相提并論。
由于內(nèi)存問題(通常稱為內(nèi)存泄漏)長(zhǎng)期以來一直伴隨著 C++ 的開發(fā)者們,Go 語言的設(shè)計(jì)者們認(rèn)為內(nèi)存管理不應(yīng)該是開發(fā)人員所需要考慮的問題。因此盡管 Go 語言像其它靜態(tài)語言一樣執(zhí)行本地代碼,但它依舊運(yùn)行在某種意義上的虛擬機(jī),以此來實(shí)現(xiàn)高效快速的垃圾回收(使用了一個(gè)簡(jiǎn)單的標(biāo)記-清除算法)。
盡管垃圾回收并不容易實(shí)現(xiàn),但考慮這將是未來并發(fā)應(yīng)用程序發(fā)展的一個(gè)重要組成部分,Go 語言的設(shè)計(jì)者們還是完成了這項(xiàng)艱難的任務(wù)。
Go 語言還能夠在運(yùn)行時(shí)進(jìn)行反射相關(guān)的操作。
使用 go install
能夠很輕松地對(duì)第三方包進(jìn)行部署。
此外,Go 語言還支持調(diào)用由 C 語言編寫的海量庫文件(第 3.9 節(jié)),從而能夠?qū)⑦^去開發(fā)的軟件進(jìn)行快速遷移。
Go語言通過減少關(guān)鍵字的數(shù)量(25 個(gè))來簡(jiǎn)化編碼過程中的混亂和復(fù)雜度。干凈、整齊和簡(jiǎn)潔的語法也能夠提高程序的編譯速度,因?yàn)檫@些關(guān)鍵字在編譯過程中少到甚至不需要符號(hào)表來協(xié)助解析。
這些方面的工作都是為了減少編碼的工作量,甚至可以與 Java 的簡(jiǎn)化程度相比較。
Go 語言有一種極簡(jiǎn)抽象藝術(shù)家的感覺,因?yàn)樗惶峁┝艘坏絻煞N方法來解決某個(gè)問題,這使得開發(fā)者們的代碼都非常容易閱讀和理解。眾所周知,代碼的可讀性是軟件工程里最重要的一部分( 譯者注:代碼是寫給人看的,不是寫給機(jī)器看的 )。
這些設(shè)計(jì)理念沒有建立其它概念之上,所以并不會(huì)因?yàn)闋砍兜揭恍└拍疃鴮⒛硞€(gè)概念復(fù)雜化,他們之間是相互獨(dú)立的。
Go 語言有一套完整的編碼規(guī)范,你可以在 Go 語言編碼規(guī)范 頁面進(jìn)行查看。
它不像 Ruby 那樣通過實(shí)現(xiàn)過程來定義編碼規(guī)范。作為一門具有明確編碼規(guī)范的語言,它要求可以采用不同的編譯器如 gc 和 gccgo(第 2.1 節(jié))進(jìn)行編譯工作,這對(duì)語言本身擁有更好的編碼規(guī)范起到很大幫助。
LALR 是 Go 語言的語法標(biāo)準(zhǔn),你也可以在 src/cmd/internal/gc/go.y
中查看到,這種語法標(biāo)準(zhǔn)在編譯時(shí)不需要符號(hào)表來協(xié)助解析。
Go 語言從本質(zhì)上(程序和結(jié)構(gòu)方面)來實(shí)現(xiàn)并發(fā)編程。
因?yàn)?Go 語言沒有類和繼承的概念,所以它和 Java 或 C++ 看起來并不相同。但是它通過接口(interface)的概念來實(shí)現(xiàn)多態(tài)性。Go 語言有一個(gè)清晰易懂的輕量級(jí)類型系統(tǒng),在類型之間也沒有層級(jí)之說。因此可以說這是一門混合型的語言。
在傳統(tǒng)的面向?qū)ο笳Z言中,使用面向?qū)ο缶幊碳夹g(shù)顯得非常臃腫,它們總是通過復(fù)雜的模式來構(gòu)建龐大的類型層級(jí),這違背了編程語言應(yīng)該提升生產(chǎn)力的宗旨。
函數(shù)是 Go 語言中的基本構(gòu)件,它們的使用方法非常靈活。在第六章,我們會(huì)看到 Go 語言在函數(shù)式編程方面的基本概念。
Go 語言使用靜態(tài)類型,所以它是類型安全的一門語言,加上通過構(gòu)建到本地代碼,程序的執(zhí)行速度也非常快。
作為強(qiáng)類型語言,隱式的類型轉(zhuǎn)換是不被允許的,記住一條原則:讓所有的東西都是顯式的。
Go 語言其實(shí)也有一些動(dòng)態(tài)語言的特性(通過關(guān)鍵字 var
),所以它對(duì)那些逃離 Java 和 .Net 世界而使用 Python、Ruby、PHP 和 JavaScript 的開發(fā)者們也具有很大的吸引力。
Go 語言支持交叉編譯,比如說你可以在運(yùn)行 Linux 系統(tǒng)的計(jì)算機(jī)上開發(fā)運(yùn)行下 Windows 下運(yùn)行的應(yīng)用程序。這是第一門完全支持 UTF-8 的編程語言,這不僅體現(xiàn)在它可以處理使用 UTF-8 編碼的字符串,就連它的源碼文件格式都是使用的 UTF-8 編碼。Go 語言做到了真正的國(guó)際化!
Go 語言被設(shè)計(jì)成一門應(yīng)用于搭載 Web 服務(wù)器,存儲(chǔ)集群或類似用途的巨型中央服務(wù)器的系統(tǒng)編程語言。對(duì)于高性能分布式系統(tǒng)領(lǐng)域而言,Go 語言無疑比大多數(shù)其它語言有著更高的開發(fā)效率。它提供了海量并行的支持,這對(duì)于游戲服務(wù)端的開發(fā)而言是再好不過了。
Go 語言一個(gè)非常好的目標(biāo)就是實(shí)現(xiàn)所謂的復(fù)雜事件處理(CEP),這項(xiàng)技術(shù)要求海量并行支持,高度的抽象化和高性能。當(dāng)我們進(jìn)入到物聯(lián)網(wǎng)時(shí)代,CEP 必然會(huì)成為人們關(guān)注的焦點(diǎn)。
但是 Go 語言同時(shí)也是一門可以用于實(shí)現(xiàn)一般目標(biāo)的語言,例如對(duì)于文本的處理,前端展現(xiàn),甚至像使用腳本一樣使用它。
值得注意的是,因?yàn)槔厥蘸妥詣?dòng)內(nèi)存分配的原因,Go 語言不適合用來開發(fā)對(duì)實(shí)時(shí)性要求很高的軟件。
越來越多的谷歌內(nèi)部的大型分布式應(yīng)用程序都開始使用 Go 語言來開發(fā),例如谷歌地球的一部分代碼就是由 Go 語言完成的。
如果你想知道一些其它組織使用Go語言開發(fā)的實(shí)際應(yīng)用項(xiàng)目,你可以到 使用 Go 的組織 頁面進(jìn)行查看。出于隱私保護(hù)的考慮,許多公司的項(xiàng)目都沒有展示在這個(gè)頁面。我們將會(huì)在第 21 章討論到一個(gè)使用 Go 語言開發(fā)的大型存儲(chǔ)區(qū)域網(wǎng)絡(luò)(SAN)案例。
在 Chrome 瀏覽器中內(nèi)置了一款 Go 語言的編譯器用于本地客戶端(NaCl),這很可能會(huì)被用于在 Chrome OS 中執(zhí)行 Go 語言開發(fā)的應(yīng)用程序。
Go 語言可以在 Intel 或 ARM 處理器上運(yùn)行,因此它也可以在安卓系統(tǒng)下運(yùn)行,例如 Nexus 系列的產(chǎn)品。
在 Google App Engine 中使用 Go 語言:2011 年 5 月 5 日,官方發(fā)布了用于開發(fā)運(yùn)行在 Google App Engine 上的 Web 應(yīng)用的 Go SDK,在此之前,開發(fā)者們只能選擇使用 Python 或者 Java。這主要是 David Symonds 和 Nigel Tao 努力的成果。目前最新的穩(wěn)定版是基于 Go 1.4 的 SDK 1.9.18,于 2015 年 2 月 18 日發(fā)布。當(dāng)前 Go 語言的穩(wěn)定版本是 Go 1.4.2。
許多能夠在大多數(shù)面向?qū)ο笳Z言中使用的特性 Go 語言都沒有支持,但其中的一部分可能會(huì)在未來被支持。
recover
和 panic
來替代異常機(jī)制(第 13.2-3 節(jié))關(guān)于 Go 語言開發(fā)團(tuán)隊(duì)對(duì)于這些方面的討論,你可以通過 Go 常見問題 頁面查看。
如果你有其它語言的編程經(jīng)歷(面向?qū)ο缶幊陶Z言,如:Java、C#、Object-C、Python、Ruby),在你進(jìn)入到 Go 語言的世界之后,你將會(huì)像迷戀你的 X 語言一樣無法自拔。Go 語言使用了與其它語言不同的設(shè)計(jì)模式,所以當(dāng)你嘗試將你的X語言的代碼遷移到 Go 語言時(shí),你將會(huì)非常失望,所以你需要從頭開始,用 Go 的理念來思考。
如果你在至高點(diǎn)使用 Go 的理念來重新審視和分析一個(gè)問題,你通常會(huì)找到一個(gè)適用于 Go 語言的優(yōu)雅的解決方案。
這里列舉一些 Go 語言的必殺技: