Go語言編程

出版時間:2012-8  出版社:人民郵電出版社  作者:許式偉  
Tag標簽:無  

前言

  為什么我們需要一門新語言  編程語言已經(jīng)非常多,偏性能敏感的編譯型語言有 C、C++、Java、C#、Delphi和Objective-C等,偏快速業(yè)務(wù)開發(fā)的動態(tài)解析型語言有 PHP、Python、Perl、Ruby、JavaScript和Lua等,面向特定領(lǐng)域的語言有 Erlang、R和MATLAB等,那么我們?yōu)槭裁葱枰?Go這樣一門新語言呢?  在2000年前的單機時代, C語言是編程之王。隨著機器性能的提升、軟件規(guī)模與復雜度的提高,Java逐步取代了C的位置。盡管看起來 Java已經(jīng)深獲人心,但 Java編程的體驗并未盡如人意。歷年來的編程語言排行榜(如圖 0-1所示)顯示, Java語言的市場份額在逐步下跌,并趨近于 C語言的水平,顯示了這門語言后勁不足?! D0-1編程語言排行榜①  Go語言官方自稱,之所以開發(fā) Go語言,是因為“近 10年來開發(fā)程序之難讓我們有點沮喪”。這一定位暗示了 Go語言希望取代 C和Java的地位,成為最流行的通用開發(fā)語言。 Go希望成為互聯(lián)網(wǎng)時代的 C語言。多數(shù)系統(tǒng)級語言(包括 Java和C#)的根本編程哲學來源于  —————————— ?、? 據(jù)來源: http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html?! ++,將C++的面向?qū)ο筮M一步發(fā)揚光大。但是Go語言的設(shè)計者卻有不同的看法,他們認為C++ 真的沒啥好學的,值得學習的是 C語言。C語言經(jīng)久不衰的根源是它足夠簡單。因此, Go語言也要足夠簡單!  那么,互聯(lián)網(wǎng)時代的 C語言需要考慮哪些關(guān)鍵問題呢?首先,并行與分布式支持。多核化和集群化是互聯(lián)網(wǎng)時代的典型特征。作為一個互聯(lián)網(wǎng)時代的C語言,必須要讓這門語言操作多核計算機與計算機集群如同操作單機一樣容易。其次,軟件工程支持。工程規(guī)模不斷擴大是產(chǎn)業(yè)發(fā)展的必然趨勢。單機時代語言可以只關(guān)心問題本身的解決,而互聯(lián)網(wǎng)時代的 C語言還需要考慮軟件品質(zhì)保障和團隊協(xié)作相關(guān)的話題。最后,編程哲學的重塑。計算機軟件經(jīng)歷了數(shù)十年的發(fā)展,形成了面向?qū)ο蟮榷喾N學術(shù)流派。什么才是最佳的編程實踐?作為互聯(lián)網(wǎng)時代的 C語言,需要回答這個問題。接下來我們來聊聊 Go語言在這些話題上是如何應(yīng)對的?! 〔l(fā)與分布式  多核化和集群化是互聯(lián)網(wǎng)時代的典型特征,那語言需要哪些特性來應(yīng)對這些特征呢?第一個話題是并發(fā)執(zhí)行的“執(zhí)行體”。執(zhí)行體是個抽象的概念,在操作系統(tǒng)層面有多個概念與之對應(yīng),比如操作系統(tǒng)自己掌管的進程( process)、進程內(nèi)的線程( thread)以及進程內(nèi)的協(xié)程  (coroutine,也叫輕量級線程)。多數(shù)語言在語法層面并不直接支持協(xié)程,而通過庫的方式支持的協(xié)程的功能也并不完整,比如僅僅提供協(xié)程的創(chuàng)建、銷毀與切換等能力。如果在這樣的協(xié)程中調(diào)用一個同步 IO操作,比如網(wǎng)絡(luò)通信、本地文件讀寫,都會阻塞其他的并發(fā)執(zhí)行協(xié)程,從而無法真正達到協(xié)程本身期望達到的目標。  Go語言在語言級別支持協(xié)程,叫 goroutine。Go語言標準庫提供的所有系統(tǒng)調(diào)用( syscall)操作,當然也包括所有同步 IO操作,都會出讓 CPU給其他goroutine,這讓事情變得非常簡單。我們對比一下Java和Go,近距離觀摩下兩者對“執(zhí)行體”的支持?! 榱撕喕覀冊跇永惺褂玫氖?Java標準庫中的線程,而不是協(xié)程,具體代碼如下:  public class MyThread implements Runnable {  String arg;  public MyThread(String a) { arg = a; }  public void run() { // ... }  public static void main(String[] args) { new Thread(new MyThread(“”test“”)).start(); // ...  }  }  相同功能的代碼,在 Go語言中是這樣的:  func run(arg string) {  // ...  }  func main() {  go run(“”test“”)  ...  }  對比非常鮮明。我相信你已經(jīng)明白為什么 Go語言會叫 Go語言了:Go語言獻給這個時代最好的禮物,就是加了 go這個關(guān)鍵字。當然也有人會說,叫 Go語言是因為它是 Google出的。好吧,這也是個不錯的閑聊主題?! 〉诙€話題是“執(zhí)行體間的通信”。執(zhí)行體間的通信包含幾個方式:  ·執(zhí)行體之間的互斥與同步  ·執(zhí)行體之間的消息傳遞  先說·執(zhí)行體之間的互斥與同步·。當執(zhí)行體之間存在共享資源(一般是共享內(nèi)存)時,為保證內(nèi)存訪問邏輯的確定性,需要對訪問該共享資源的相關(guān)執(zhí)行體進行互斥。當多個執(zhí)行體之間的邏輯存在時序上的依賴時,也往往需要在執(zhí)行體之間進行同步?;コ馀c同步是執(zhí)行體間最基礎(chǔ)的交互方式?! 《鄶?shù)語言在庫層面提供了線程間的互斥與同步支持,那么協(xié)程之間的互斥與同步呢?呃,不好意思,沒有。事實上多數(shù)語言標準庫中連協(xié)程都是看不到的?! ≡僬f·執(zhí)行體之間的消息傳遞·。在并發(fā)編程模型的選擇上,有兩個流派,一個是共享內(nèi)存模型,一個是消息傳遞模型。多數(shù)傳統(tǒng)語言選擇了前者,少數(shù)語言選擇后者,其中選擇·消息傳遞模型·的最典型代表是 Erlang語言。業(yè)界有專門的術(shù)語叫“ Erlang風格的并發(fā)模型”,其主體思想是兩點:一是“輕量級的進程( Erlang中‘進程’這個術(shù)語就是我們上面說的‘執(zhí)行體’)”,二是“消息乃進程間通信的唯一方式”。當執(zhí)行體之間需要相互傳遞消息時,通常需要基于一個消息隊列(message queue)或者進程郵箱( process mail box)這樣的設(shè)施進行通信。  Go語言推薦采用“ Erlang風格的并發(fā)模型”的編程范式,盡管傳統(tǒng)的“共享內(nèi)存模型”仍然被保留,允許適度地使用。在 Go語言中內(nèi)置了消息隊列的支持,只不過它叫通道( channel)。兩個goroutine之間可以通過通道來進行交互。  軟件工程  單機時代的語言可以只關(guān)心問題本身的解決,但是隨著工程規(guī)模的不斷擴大,軟件復雜度的不斷增加,軟件工程也成為語言設(shè)計層面要考慮的重要課題。多數(shù)軟件需要一個團隊共同去完成,在團隊協(xié)作的過程中,人們需要建立統(tǒng)一的交互語言來降低溝通的成本。規(guī)范化體現(xiàn)在多個層面,如:  ·代碼風格規(guī)范  ·錯誤處理規(guī)范  ·包管理  ·契約規(guī)范(接口)  ·單元測試規(guī)范  ·功能開發(fā)的流程規(guī)范  Go語言很可能是第一個將代碼風格強制統(tǒng)一的語言,例如 Go語言要求 public的變量必須以大寫字母開頭,private變量則以小寫字母開頭,這種做法不僅免除了public、private關(guān)鍵字,更重要的是統(tǒng)一了命名風格?! ×硗?,Go語言對 { }應(yīng)該怎么寫進行了強制,比如以下風格是正確的:  if expression { ... }  但下面這個寫法就是錯誤的:  if expression { ... }  而C和Java語言中則對花括號的位置沒有任何要求。哪種更有利,這個見仁見智。但很顯然的是,所有的 Go代碼的花括號位置肯定是非常統(tǒng)一的。最有意思的其實還是 Go語言首創(chuàng)的錯誤處理規(guī)范:  f, err := os.Open(filename)  if err != nil { log.Println(“”Open file failed:““, err) return  } defer f.Close() ... // 操作已經(jīng)打開的 f文件  這里有兩個關(guān)鍵點。其一是 defer關(guān)鍵字。 defer語句的含義是不管程序是否出現(xiàn)異常,均在函數(shù)退出時自動執(zhí)行相關(guān)代碼。在上面的例子中,正是因為有了 defer,才使得無論后續(xù)是否會出現(xiàn)異常,都可以確保文件被正確關(guān)閉。其二是 Go語言的函數(shù)允許返回多個值。大多數(shù)函數(shù)的最后一個返回值會為 error類型,以在錯誤情況下返回詳細信息。 error類型只是一個系統(tǒng)內(nèi)置的interface,如下:  type error interface { Error() string }  有了error類型,程序出現(xiàn)錯誤的邏輯看起來就相當統(tǒng)一。在Java中,你可能這樣寫代碼來保證資源正確釋放:  Connection conn = ...;  try { Statement stmt = ...; try {  ResultSet rset = ...; try {  ... // 正常代碼 } finally {  rset.close();  } } finally {  stmt.close();  } } finally {  conn.close(); }  完成同樣的功能,相應(yīng)的 Go代碼只需要寫成這樣:  conn := ... defer conn.Close()  stmt := ... defer stmt.Close()  rset := ... defer rset.Close() ... // 正常代碼  對比兩段代碼, Go語言處理錯誤的優(yōu)勢顯而易見。當然,其實 Go語言帶給我們的驚喜還有很多,后續(xù)有機會我們可以就某個更具體的話題詳細展開來談一談?! 【幊陶軐W  計算機軟件經(jīng)歷了數(shù)十年的發(fā)展,形成了多種學術(shù)流派,有面向過程編程、面向?qū)ο缶幊?、函?shù)式編程、面向消息編程等,這些思想究竟孰優(yōu)孰劣,眾說紛紜?! 語言是純過程式的,這和它產(chǎn)生的歷史背景有關(guān)。 Java語言則是激進的面向?qū)ο笾髁x推崇者,典型表現(xiàn)是它不能容忍體系里存在孤立的函數(shù)。而 Go語言沒有去否認任何一方,而是用批判吸收的眼光,將所有編程思想做了一次梳理,融合眾家之長,但時刻警惕特性復雜化,極力維持語言特性的簡潔,力求小而精?! 木幊谭妒降慕嵌葋碚f, Go語言是變革派,而不是改良派。對于C++、Java和C#等語言為代表的面向?qū)ο螅?OO)思想體系,Go語言總體來說持保守態(tài)度,有限吸收。首先,Go語言反對函數(shù)和操作符重載( overload),而C++、Java和C#都允許出現(xiàn)同名函數(shù)或操作符,只要它們的參數(shù)列表不同。雖然重載解決了一小部分面向?qū)ο缶幊蹋?OOP)的問題,但  同樣給這些語言帶來了極大的負擔。而 Go語言有著完全不同的設(shè)計哲學,既然函數(shù)重載帶來了負擔,并且這個特性并不對解決任何問題有顯著的價值,那么 Go就不提供它。其次,Go語言支持類、類成員方法、類的組合,但反對繼承,反對虛函數(shù)( virtual function)和虛函數(shù)重載。確切地說, Go也提供了繼承,只不過是采用了組合的文法來提供:  type Foo struct { Base ...  }  func (foo *Foo) Bar() { ... }  再次,Go語言也放棄了構(gòu)造函數(shù)( constructor)和析構(gòu)函數(shù)(destructor)。由于Go語言中沒有虛函數(shù),也就沒有 vptr,支持構(gòu)造函數(shù)和析構(gòu)函數(shù)就沒有太大的價值。本著“如果一個特性并不對解決任何問題有顯著的價值,那么 Go就不提供它”的原則,構(gòu)造函數(shù)和析構(gòu)函數(shù)就這樣被Go語言的作者們干掉了?! ≡诜艞壛舜罅康?OOP特性后,Go語言送上了一份非常棒的禮物:接口( interface)。你可能會說,除了 C這么原始的語言外,還有什么語言沒有接口呢?是的,多數(shù)語言都提供接口,但它們的接口都不同于 Go語言的接口?! o語言中的接口與其他語言最大的一點區(qū)別是它的非侵入性。在 C++、Java和C#中,為了實現(xiàn)一個接口,你需要從該接口繼承,具體代碼如下:  class Foo implements IFoo { // Java文法 ... }  class Foo : public IFoo { // C++文法 ... }  IFoo* foo = new Foo;  在Go語言中,實現(xiàn)類的時候無需從接口派生,具體代碼如下:  type Foo struct { // Go 文法 ... }  var foo IFoo = new(Foo)  只要Foo實現(xiàn)了接口IFoo要求的所有方法,就實現(xiàn)了該接口,可以進行賦值。 Go語言的非侵入式接口,看似只是做了很小的文法調(diào)整,實則影響深遠。其一,Go語言的標準庫再也不需要繪制類庫的繼承樹圖。你只需要知道這個類實現(xiàn)了哪些  方法,每個方法是啥含義就足夠了。其二,不用再糾結(jié)接口需要拆得多細才合理,比如我們實現(xiàn)了 File類,它有下面這些方法:  前言:為什么我們需要一門新語言  Read(buf []byte) (n int, err error) Write(buf []byte) (n int, err error) Seek(off int64, whence int) (pos int64, err error) Close() error  那么,到底是應(yīng)該定義一個 IFile接口,還是應(yīng)該定義一系列的 IReader、IWriter、 ISeeker和ICloser接口,然后讓File從它們派生好呢?事實上,脫離了實際的用戶場景,討論這兩個設(shè)計哪個更好并無意義。問題在于,實現(xiàn) File類的時候,我怎么知道外部會如何用它呢?  其三,不用為了實現(xiàn)一個接口而專門導入一個包,而目的僅僅是引用其中的某個接口的定義。在Go語言中,只要兩個接口擁有相同的方法列表,那么它們就是等同的,可以相互賦值,如對于以下兩個接口,第一個接口:  package one  type ReadWriter interface {  Read(buf [] byte) (n int, err error)  Write(buf [] byte) (n int, err error)  }  第二個接口:  package two  type IStream interface {  Write(buf [] byte) (n int, err error)  Read(buf [] byte) (n int, err error)  }  這里我們定義了兩個接口,一個叫 one.ReadWriter,一個叫 two.IStream,兩者都定義了Read()和Write()方法,只是定義的次序相反。 one.ReadWriter先定義了 Read()再定義 Write(),而two.IStream反之?! ≡贕o語言中,這兩個接口實際上并無區(qū)別,因為:  ·任何實現(xiàn)了 one.ReadWriter接口的類,均實現(xiàn)了 two.IStream;  ·任何one.ReadWriter接口對象可賦值給 two.IStream,反之亦然;  ·在任何地方使用 one.ReadWriter接口,與使用 two.IStream并無差異。所以在Go語言中,為了引用另一個包中的接口而導入這個包的做法是不被推薦的。因為多引用一個外部的包,就意味著更多的耦合。  除了OOP外,近年出現(xiàn)了一些小眾的編程哲學, Go語言對這些思想亦有所吸收。例如, Go語言接受了函數(shù)式編程的一些想法,支持匿名函數(shù)與閉包。再如, Go語言接受了以 Erlang語言為代表的面向消息編程思想,支持 goroutine和通道,并推薦使用消息而不是共享內(nèi)存來進行并發(fā)編程??傮w來說, Go語言是一個非常現(xiàn)代化的語言,精小但非常強大?! ⌒〗Y(jié)  在十余年的技術(shù)生涯中,我接觸過、使用過、喜愛過不同的編程語言,但總體而言, Go語言的出現(xiàn)是最讓我興奮的事情。我個人對未來 10年編程語言排行榜的趨勢判斷如下:  □·Java語言的份額繼續(xù)下滑,并最終被 C和Go語言超越;  □·C語言將長居編程榜第二的位置,并有望在 Go取代Java前重獲語言榜第一的寶座;  □·Go語言最終會取代 Java,居于編程榜之首。  由七牛云存儲團隊編著的這本書將盡可能展現(xiàn)出 Go語言的迷人魅力。希望本書能夠讓更多人理解這門語言,熱愛這門語言,讓這門優(yōu)秀的語言能夠落到實處,把程序員從以往繁雜的語言細節(jié)中解放出來,集中精力開發(fā)更加優(yōu)秀的系統(tǒng)軟件。  許式偉 2012年3月7日

內(nèi)容概要

  在C語言和Unix操作系統(tǒng)發(fā)布40年后,肯·湯普森等貝爾實驗室原班人馬終于推出了一門全新的編程語言,它就是Go語言。Go語言凝聚了該團隊將近半個世紀對計算機工程的思考成果,被稱為互聯(lián)網(wǎng)時代的C語言。自Go語言第一次發(fā)布以來,七牛云存儲團隊就非常密切地關(guān)注這門語言的發(fā)展,并率先在七牛的產(chǎn)品中進行大面積的應(yīng)用,而開發(fā)效率和系統(tǒng)穩(wěn)定性等客觀數(shù)據(jù)也在持續(xù)證明我們選擇Go語言的正確性。因此,我們迫不及待地希望向同行們分享這門語言,大家一起來享受Go語言所帶來的極大樂趣,也一起來促進這門語言的發(fā)展吧!  《Go語言編程》首先概覽了Go語言的誕生和發(fā)展歷程,從面向過程編程特性入手介紹Go語言的基礎(chǔ)用法,讓有一定C語言基礎(chǔ)的讀者可以非常迅速地入門并開始上手用Go語言來解決實際問題,之后介紹了Go語言簡潔卻又無比強大的面向?qū)ο缶幊烫匦院筒l(fā)編程能力,至此讀者已經(jīng)可以理解為什么Go語言是為互聯(lián)網(wǎng)時代而生的語言。從實用性角度出發(fā),本書還介紹了Go語言標準庫和配套工具的用法,包括安全編程、網(wǎng)絡(luò)編程、工程管理工具等。對于希望對Go語言有更深入了解的讀者,我們也特別組織了一系列進階話題,包括語言交互性、鏈接符號、goroutine機理和接口機制等?!禛o語言編程》適合所有層次的開發(fā)者閱讀。

作者簡介

許式偉,七牛云存儲CEO,曾任盛大創(chuàng)新院資深研究員、金山軟件技術(shù)總監(jiān)、WPS Office 2005首席架構(gòu)師。開源愛好者,發(fā)布過WINX、TPL等十余個C++開源項目,擁有超過15年的C/C++開發(fā)經(jīng)驗。在接觸Go語言后即被其大道至簡、少即是多的設(shè)計哲學所傾倒。七牛云存儲是國內(nèi)第一個吃螃蟹的團隊,核心服務(wù)完全采用Go語言實現(xiàn)。呂桂華,七牛云存儲聯(lián)合創(chuàng)始人,曾在金山軟件、盛大游戲等公司擔任架構(gòu)師和部門經(jīng)理等職務(wù),在企業(yè)級系統(tǒng)和大型網(wǎng)游平臺領(lǐng)域有較多涉獵。擁有十余年的C/C++大型項目開發(fā)經(jīng)驗,也曾在Java和.NET平臺上探索多年。同樣被Go語言的魅力所吸引而不可自拔,希望能為推廣這門優(yōu)秀的語言盡自己的綿薄之力。

書籍目錄

目 錄 第1章 初識Go語言 11.1 語言簡史 11.2 語言特性 21.2.1 自動垃圾回收 31.2.2 更豐富的內(nèi)置類型 41.2.3 函數(shù)多返回值 51.2.4 錯誤處理 61.2.5 匿名函數(shù)和閉包 61.2.6 類型和接口 71.2.7 并發(fā)編程 81.2.8 反射 91.2.9 語言交互性 101.3 第一個Go程序 111.3.1 代碼解讀 111.3.2 編譯環(huán)境準備 121.3.3 編譯程序 121.4 開發(fā)工具選擇 131.5 工程管理 131.6 問題追蹤和調(diào)試 181.6.1 打印日志 181.6.2 GDB調(diào)試 181.7 如何尋求幫助 181.7.1 郵件列表 191.7.2 網(wǎng)站資源 191.8 小結(jié) 19第2章 順序編程 202.1 變量 202.1.1 變量聲明 202.1.2 變量初始化 212.1.3 變量賦值 212.1.4 匿名變量 222.2 常量 222.2.1 字面常量 222.2.2 常量定義 232.2.3 預定義常量 232.2.4 枚舉 242.3 類型 242.3.1 布爾類型 252.3.2 整型 252.3.3 浮點型 272.3.4 復數(shù)類型 282.3.5 字符串 282.3.6 字符類型 302.3.7 數(shù)組 312.3.8 數(shù)組切片 322.3.9 map 362.4 流程控制 382.4.1 條件語句 382.4.2 選擇語句 392.4.3 循環(huán)語句 402.4.4 跳轉(zhuǎn)語句 412.5 函數(shù) 412.5.1 函數(shù)定義 422.5.2 函數(shù)調(diào)用 422.5.3 不定參數(shù) 432.5.4 多返回值 452.5.5 匿名函數(shù)與閉包 452.6 錯誤處理 472.6.1 error接口 472.6.2 defer 482.6.3 panic()和recover() 492.7 完整示例 502.7.1 程序結(jié)構(gòu) 512.7.2 主程序 512.7.3 算法實現(xiàn) 542.7.4 主程序 572.7.5 構(gòu)建與執(zhí)行 592.8 小結(jié) 61第3章 面向?qū)ο缶幊獭?23.1 類型系統(tǒng) 623.1.1 為類型添加方法 633.1.2 值語義和引用語義 663.1.3 結(jié)構(gòu)體 673.2 初始化 683.3 匿名組合 683.4 可見性 713.5 接口 713.5.1 其他語言的接口 713.5.2 非侵入式接口 733.5.3 接口賦值 743.5.4 接口查詢 763.5.5 類型查詢 783.5.6 接口組合 783.5.7 Any類型 793.6 完整示例 793.6.1 音樂庫 803.6.2 音樂播放 823.6.3 主程序 843.6.4 構(gòu)建運行 863.6.5 遺留問題 863.7 小結(jié) 87第4章 并發(fā)編程 884.1 并發(fā)基礎(chǔ) 884.2 協(xié)程 904.3 goroutine 904.4 并發(fā)通信 914.5 channel 944.5.1 基本語法 954.5.2 select 954.5.3 緩沖機制 964.5.4 超時機制 974.5.5 channel的傳遞 984.5.6 單向channel 984.5.7 關(guān)閉channel 994.6 多核并行化 1004.7 出讓時間片 1014.8 同步 1014.8.1 同步鎖 1014.8.2 全局唯一性操作 1024.9 完整示例 1034.9.1 簡單IPC框架 1054.9.2 中央服務(wù)器 1084.9.3 主程序 1134.9.4 運行程序 1164.10 小結(jié) 117第5章 網(wǎng)絡(luò)編程 1185.1 Socket編程 1185.1.1 Dial()函數(shù) 1185.1.2 ICMP示例程序 1195.1.3 TCP示例程序 1215.1.4 更豐富的網(wǎng)絡(luò)通信 1225.2 HTTP編程 1245.2.1 HTTP客戶端 1245.2.2 HTTP服務(wù)端 1305.3 RPC編程 1325.3.1 Go語言中的RPC支持與處理 1325.3.2 Gob簡介 1345.3.3 設(shè)計優(yōu)雅的RPC接口 1345.4 JSON處理 1355.4.1 編碼為JSON格式 1365.4.2 解碼JSON數(shù)據(jù) 1375.4.3 解碼未知結(jié)構(gòu)的JSON數(shù)據(jù) 1385.4.4 JSON的流式讀寫 1405.5 網(wǎng)站開發(fā) 1405.5.1 最簡單的網(wǎng)站程序 1415.5.2 net/http包簡介 1415.5.3 開發(fā)一個簡單的相冊網(wǎng)站 1425.6 小結(jié) 157第6章 安全編程 1586.1 數(shù)據(jù)加密 1586.2 數(shù)字簽名 1586.3 數(shù)字證書 1596.4 PKI體系 1596.5 Go語言的哈希函數(shù) 1596.6 加密通信 1606.6.1 加密通信流程 1616.6.2 支持HTTPS的Web服務(wù)器 1626.6.3 支持HTTPS的文件服務(wù)器 1656.6.4 基于SSL/TLS的ECHO程序 1666.7 小結(jié) 169第7章 工程管理 1707.1 Go命令行工具 1707.2 代碼風格 1727.2.1 強制性編碼規(guī)范 1727.2.2 非強制性編碼風格建議 1737.3 遠程import支持 1757.4 工程組織 1757.4.1 GOPATH 1767.4.2 目錄結(jié)構(gòu) 1767.5 文檔管理 1777.6 工程構(gòu)建 1807.7 跨平臺開發(fā) 1807.7.1 交叉編譯 1817.7.2 Android支持 1827.8 單元測試 1837.9 打包分發(fā) 1847.10 小結(jié) 184第8章 開發(fā)工具 1868.1 選擇開發(fā)工具 1868.2 gedit 1878.2.1 語法高亮 1878.2.2 編譯環(huán)境 1878.3 Vim 1888.4 Eclipse 1898.5 Notepad++ 1928.5.1 語法高亮 1928.5.2 編譯環(huán)境 1928.6 LiteIDE 1938.7 小結(jié) 195第9章 進階話題 1969.1 反射 1969.1.1 基本概念 1969.1.2 基本用法 1979.1.3 對結(jié)構(gòu)的反射操作 1999.2 語言交互性 1999.2.1 類型映射 2009.2.2 字符串映射 2019.2.3 C程序 2019.2.4 函數(shù)調(diào)用 2029.2.5 編譯Cgo 2039.3 鏈接符號 2039.4 goroutine機理 2049.4.1 協(xié)程 2049.4.2 協(xié)程的C語言實現(xiàn) 2059.4.3 協(xié)程庫概述 2059.4.4 任務(wù) 2089.4.5 任務(wù)調(diào)度 2109.4.6 上下文切換 2119.4.7 通信機制 2159.5 接口機理 2169.5.1 類型賦值給接口 2179.5.2 接口查詢 2239.5.3 接口賦值 224附錄A 225

媒體關(guān)注與評論

這本書除了完整介紹Go語言特性之外,還深入剖析了語言實現(xiàn)機制。作為服務(wù)器軟件開發(fā)者和編程語言愛好者,我強烈推薦此書。——李杰,盛大文學首席架構(gòu)師《Go語言編程》正是這樣一份猛料,能夠帶領(lǐng)越來越多的人了解Go,學習Go,用Go來實現(xiàn)自己的夢想?!螘越?,國內(nèi)知名Android研究者,安居客移動事業(yè)部高級開發(fā)經(jīng)理《Go語言編程》這本書應(yīng)當說是作者多年編程經(jīng)驗的沉淀和反思。本書一方面通過展示和分析大量Go語言代碼,闡明了Go語言基本的使用方式,另一方面通過和C語言代碼進行比較,進一步剖析了語言的內(nèi)在設(shè)計思想,乃至底層實現(xiàn)原理,讓各個層次的讀者都能從書中汲取到大量的知識,使人讀后必有所得。——邢星,Go語言社區(qū)積極推動者,39健康網(wǎng)技術(shù)部副總監(jiān)

編輯推薦

國內(nèi)第一本Go語言編程書原盛大創(chuàng)新院研究員執(zhí)筆Go語言領(lǐng)域技術(shù)大牛作品作者Go語言開發(fā)實戰(zhàn)項目幫助您快速入手全新語言

圖書封面

圖書標簽Tags

評論、評分、閱讀與下載


    Go語言編程 PDF格式下載


用戶評論 (總計22條)

 
 

  •   說實話,這本書寫得很一般,鑒于許很熱衷于開源事業(yè),樂于推動golang發(fā)展才給3星。。。說說我的想法吧。。最初,我想買這本書,主要是因為許做了golang的實際開發(fā),我以為會有很多經(jīng)驗分享。事實上。。。反正我是失望很大。。如果你是想看它怎么教你寫go語法的,我覺得不怎么適合,網(wǎng)上有本《學習go語言》的書(開源,可以直接下到高清pdf)個人覺得介紹得更有條理,簡潔明了,清晰易懂。因為這本說講語法很不集中,寫的有點散亂。有的語法我在別人的代碼里看過,但書里貌似沒有。如果你是想通過里面的代碼學習,我也很不建議。代碼質(zhì)量我不評價,n多例子貼一次就算了,還要兩三次的在不同章節(jié)貼,這個有點惡心了,本來書就不厚。。。代碼最好打包放到網(wǎng)上吧。至于應(yīng)用,本來go的核心是goroutine,至少我想看的是網(wǎng)絡(luò)編程和goroutine的結(jié)合,不過書中后面的大部分章節(jié)都是講web編程。這個也就算了,關(guān)鍵還說得非常簡單。。。標準庫的話也基本沒介紹多少,tcp大概就三五面,加密就那么兩個簡單的md5update的例子,至于rpc也是兩面。。。至于高級點的部分,和C的交互也是三言兩語帶過,其他的我就不想說了至于其他的方面,比如語言表述過于口語話,這個我就諒解了。。。暫時還沒看到好的...介紹go的書。沒事去github上看大牛寫的代碼吧。。。哎,失望極了好吧,對于這本書來說,我算是高級黑吧,許式偉很熱衷開源,這點我還是很敬重的。。 閱讀更多 ›
  •   書主要分三部分, 第一部分是Go語言基本的語法; 第二部分是Go語言的特點, 例如goroutine和interface; 第三部分是一些網(wǎng)絡(luò)開發(fā)實例, 最后還有一些關(guān)于工程和閑聊的話題.    嚴格來說, 三個部分都不合格. 第一部分主要問題是比較雜亂, 屬于羅列語言特性. 組織得并不好也沒有能夠深入講解一下(例如make的原理). 但總的來說還算可以接受.    第二部分的問題比較大, 有個事實錯誤是在介紹Go關(guān)鍵字時, 作者說goroutine是基于輕量級線程(即線程coroutine, 原書90頁). 在第九章進階話題中, 作者又一次提到, "從根本上來說, goroutine就是一種go語言版本的協(xié)程(coroutine)" (原書204頁). 可是作者都沒有給出任何的理由, 僅僅提到他相信如此.  其實翻看一下Effective Go, 就可以看到書中說: "之所以這個機制被稱為goroutine, 就是因為現(xiàn)存的進程, 線程和協(xié)程的概念, 都無法準確的表達它". 根據(jù)我目前看到的討論, goroutine本質(zhì)應(yīng)該是一種優(yōu)化過的, 由運行時庫進行動態(tài)分配??臻g的線程.    第三部分根本毫無意義, 不但代碼就是go語言參考里面的實例代碼, 連文字描述頁僅僅是翻譯了手冊而已.
  •   書里面的代碼有很多錯,不過感覺有些內(nèi)容說得還可以
  •   用來入門足夠了,另外書中有很多代碼錯誤
  •   不錯的書,給老公買的,他喜歡看這類書!
  •   入門級的GO語言書籍,很好.
  •   書中代碼有很多的錯誤……這一點讓我非常失望。感覺寫作很不嚴謹。而且語法的介紹也不系統(tǒng)不具體。例如講到make的時候一筆帶過,根本不清楚具體的用法。感覺這本書不是非常合適入門學習。
  •   需要有點C的基礎(chǔ)。文字挺簡單,講解不是特別詳細,入門可以。
  •   這本書大致講解了GO語言的特性,但本人覺得很多東西都是一筆帶過了。
  •   本書,不適合0基礎(chǔ)的人讀,最好有c語言基礎(chǔ)的人看
  •   內(nèi)容簡單易懂,結(jié)合實例講解,適合入門學習
  •   入門不錯的書,good
  •   書不錯 就是有點皺,內(nèi)容很好
  •   適合GO入門者學習
  •   Go語言
  •   編程用的,有幫助吧
  •   還可以 繼續(xù)學習中
  •   手游開發(fā)必備。。
  •     書多數(shù)部分反復強調(diào)一句話go比XX好、優(yōu)秀,實在的東西寫得比較淺,章節(jié)跨度優(yōu)秀大。goroutin select 介紹不足。總的來書,看過之后很失望,無處不在的吹捧模式,讓人生厭。對go有很好的期待,就不要看這個書了,真的佷差。我比較喜歡go的oo方式,channel + go比erlang actor,還有一些不便之處,更像是lib,不像erlang的solution。
  •     我在新浪微博、《Go語言編程》一書中下了一個論斷:Go語言將超過C、Java,成為未來十年最流行的語言。
      
      
      我曾在2007年第2屆ECUG大會上提到了我對未來軟件產(chǎn)業(yè)趨勢的判斷:存儲與計算將向服務(wù)端轉(zhuǎn)移;PC單機轉(zhuǎn)換為強悍的服務(wù)器+多元化的終端。這個趨勢判斷對我的職業(yè)生涯其實影響非常重大。
      
      從業(yè)務(wù)角度講,正因為這個判斷,促使我選擇成立金山實驗室研究云存儲技術(shù);也促使我關(guān)注Erlang這門面向分布式編程的領(lǐng)域性語言;促使我舉辦了一屆屆的ECUG大會;促使我加入盛大創(chuàng)新院,發(fā)起祥云計劃(盛大云前身),做盛大網(wǎng)盤;促使我們成立了七牛,有了七牛云存儲。
      
      從技術(shù)角度來講,它促使我放棄了近10年的桌面開發(fā)經(jīng)驗,轉(zhuǎn)向服務(wù)端開發(fā)。正如我在《我為什么選擇了Erlang》中建議的那樣:
      
      要么不寫程序,要么就寫服務(wù)器端程序;
      當然,你也可以去撰寫移動終端設(shè)備上的代碼,在PC平臺上做開發(fā)的空間很小。
      
      在金山實驗室時,我選擇了Java語言,并積極關(guān)注Erlang語言,對其進行小范圍試用,以及大規(guī)模使用的可行性評估。我的結(jié)論是:
      
      Erlang風格的并行思想真的很棒;
      Erlang語言優(yōu)勢與劣勢同樣明顯,這門語言不適合規(guī)?;茝V使用。
      
      Erlang的困難之處在于它是FP語言。我們?nèi)狈ι钊肴诵牡腇P編程理論。我們并不了解FP“數(shù)據(jù)結(jié)構(gòu)”學。這是Erlang語言無法逾越的門檻,決定了它只能是小眾化語言。
      
      進入盛大創(chuàng)新院后,我選擇了C++,原因是我個人更喜歡C++,而對Java的設(shè)計哲學非常不感興趣。出于對Erlang風格的并行思想的喜愛,我創(chuàng)建了一個名為CERL的項目,取義Erlang Model for C++,表明我希望能夠把Erlang那一套并行編程模型搬到 C++中來,降低分布式編程的負擔。
      
      接觸Go語言后,我發(fā)現(xiàn)CERL 2.0的并發(fā)編程模型,其實就是一個雛形版的Go語言并發(fā)模型,兩者從理念上來說完全一致。
      
      七牛公司成立于2011年5月底,我們選擇了Go語言作為七牛云存儲服務(wù)端的主體語言。當時Go語言甚至語法都還沒完全穩(wěn)定下來。為什么我可以如此堅定地相信,選擇Go語言不會有錯,并且相信Go語言會成為未來十年最流行的語言?除了Go語言的并發(fā)編程模型深得我心外,Go語言的各種語法特性顯得那么深思熟慮、卓絕不凡,其對軟件系統(tǒng)架構(gòu)的領(lǐng)悟,處處帶給我驚喜。
      
      Go語言給我的第一個意外驚喜,是接口。當然,我意外的不是Go的非侵入式接口。在接口(或契約)的表達上,我一直認為Java和C#這些主流的靜態(tài)類型語言都走錯了方向。C++的模板盡管機制復雜,但走在了正確的方向上。但Go語言的接口遠不是非侵入式接口那么簡單,它是Go語言類型系統(tǒng)的綱。除了支持反射等高級特性外,Go語言還支持接口查詢。
      
      Go語言給我的第二個意外驚喜,是極度簡化但完備的“面向?qū)ο缶幊獭狈椒?。Go語言廢棄大量的OOP特性,如繼承、構(gòu)造/析構(gòu)函數(shù)、虛函數(shù)、函數(shù)重載、默認參數(shù)等;簡化的符號訪問權(quán)限控制、將隱藏的this指針改為顯式定義的receiver對象。讓我看到了OOP編程核心價值原來如此簡單—只是多數(shù)人都無法看透。
      
      Go語言帶給我的第三個驚喜,是它的函數(shù)多反回值和錯誤處理規(guī)范。函數(shù)多返回值比較容易想到,只有這樣函數(shù)的輸入輸出才能清晰呈現(xiàn),語義表達上才會足夠清晰。不過讓我沒想到的是,Go引入了內(nèi)置的error類型以及defer關(guān)鍵字來編寫異常安全代碼,讓人拍案叫絕。
      
      Go語言帶給我的第四個驚喜,是它功能的內(nèi)聚。一個最典型的案例是Go語言的組合功能。對于多數(shù)語言來說,組合只是形成復合類型的基本手段。但Go語言引入了匿名組合的概念,讓其他語言原本需要引入繼承甚至虛擬繼承這樣晦澀概念來完成的事情,統(tǒng)一到了組合這樣的一個基礎(chǔ)上。
      
      Go語言帶給我的第五個驚喜,是消除了堆與棧的邊界。在Go語言之前,程序員是清楚地知道哪些變量在棧上,哪些變量在堆上。堆與棧是基于現(xiàn)代計算機系統(tǒng)的基礎(chǔ)工作模型上形成的概念,Go語言屏蔽了變量定義在堆還是棧上這樣的物理結(jié)構(gòu),相當于封裝了一個新的計算機工作模型。這一點看似與Go語言顯式表達的設(shè)計哲學不太一致,但我認為這是一項了不起的工作,且與Go語言的顯式表達并不矛盾。Go語言強調(diào)的是對開發(fā)者的程序邏輯(語義)的顯式表達,而非對計算機硬件結(jié)構(gòu)的顯示表達。對計算機硬件結(jié)構(gòu)的高度抽象,將更有助于Go語言適應(yīng)計算機硬件發(fā)展的變化。
      
      Go語言帶給我的第六個驚喜,是Go語言對C語言的支持??梢赃@么說,Go語言是除了Objective-C、C++這兩門以兼容C為基礎(chǔ)目標的語言外的所有語言中,對C語言支持最友善的一個。什么語言可以直接嵌入C代碼?沒有,除了Go。什么語言可以無縫調(diào)用C函數(shù)?沒有,除了Go。對C語言的完美支持,是Go快速崛起的關(guān)鍵支撐。還有比C語言更讓人覬覦的社區(qū)財富嗎?那是一個取之不盡的金礦。
      
      在《Go語言編程》一書的前言中,我談到Go語言的基礎(chǔ)哲學來源于C語言,而不是像Java、C#那樣,學的是C++。C語言的成功在于它足夠簡單,所以Go語言也要非常簡單。Go語言的定位就是成為互聯(lián)網(wǎng)時代的C語言。本質(zhì)上來說,Go語言的特性都圍繞著以下設(shè)計哲學:
      
      大道至簡,顯式表達。任何封裝都是有漏洞的。最佳的表達方式就是最直白的表達方式,不試圖去做任何包裝。
      最少特性原則。如果一個功能不對解決任何問題有顯著價值,那么就不提供。
      
      盡管是40年來出現(xiàn)的語言非常之多,但我認為,談得上突破了C語言思想,將編程理念提高到一個新高度的,僅有Go語言而已。
      
      Go語言是一門變革性的語言,要革的是C的命(順便革Java的命)。Go語言很簡單,但具備極強的表現(xiàn)力。從目前的狀態(tài)來說,Go語言主要關(guān)注服務(wù)器領(lǐng)域的開發(fā),但這不是Go語言的完整使命。
      
      我們說Go語言適合服務(wù)端開發(fā),僅是因為它的標準庫支持方面,目前是向服務(wù)端開發(fā)傾斜:
      
      網(wǎng)絡(luò)庫(包括 Socket、HTTP、RPC 等);
      編碼庫(包括 JSON、XML、GOB等);
      加密庫(各種加密算法、摘要算法);
      Web(包括 Template、HTML支持)。
      
      而作為桌面開發(fā)的常規(guī)組件GDI和UI系統(tǒng)與事件處理,基本沒有涉及。
      
      總之,我認為,Go語言將引領(lǐng)未來10年IT產(chǎn)業(yè)的發(fā)展。在最初5年內(nèi),Go語言會在服務(wù)器端編程上大放異彩,而桌面端的開發(fā)則仍然處于探索和完善期,預計在后5年才趨于成熟,成為各種手持設(shè)備上的主流開發(fā)語言之一。
      
      作者許式偉,七牛云存儲CEO,曾任盛大創(chuàng)新院資深研究員、金山軟件技術(shù)總監(jiān)、WPS Office 2005首席架構(gòu)師。開源愛好者,發(fā)布過包括WINX、TPL等十余個C++開源項目,擁有超過15年的C/C++開發(fā)經(jīng)驗。在接觸Go語言后即可被其大道至簡、少即是多的設(shè)計哲學所傾倒。七牛云存儲是國內(nèi)第一個吃螃蟹的團隊,核心服務(wù)完全采用Go語言實現(xiàn)。
      
      本文首發(fā)《程序員雜志》經(jīng)其允許轉(zhuǎn)載。 本文選自《程序員》雜志2012年10期
  •   默認參數(shù)什么時候成了OOP特性了?
  •   @liutos
    淡定啦淡定。。
    interface都能成為C++關(guān)鍵字嘛!
 

250萬本中文圖書簡介、評論、評分,PDF格式免費下載。 第一圖書網(wǎng) 手機版

京ICP備13047387號-7