2015-12-09 07:45:11 +00:00
## 1.1. Hello, World
2016-01-20 05:05:00 +00:00
我們以現已成爲傳統的“hello world”案例來開始吧, 這個例子首次出現於1978年出版的C語言聖經[《The C Programming Language》](http://s3-us-west-2.amazonaws.com/belllabs-microsite-dritchie/cbook/index.html)。( 譯註: 本書作者之一Brian W. Kernighan也是C語言聖經一書的作者) 。C語言是直接影響Go語言設計的語言之一。這個例子體現了Go語言一些核心理念。
2015-12-09 07:45:11 +00:00
```go
2015-12-22 12:49:16 +00:00
gopl.io/ch1/helloworld
2015-12-09 07:45:11 +00:00
package main
import "fmt"
func main() {
2015-12-22 02:37:13 +00:00
fmt.Println("Hello, 世界")
2015-12-09 07:45:11 +00:00
}
```
2016-01-19 15:19:32 +00:00
Go是一門編譯型語言, Go語言的工具鏈將源代碼及其依賴轉換成計算機的機器指令(譯註:靜態編譯)。Go語言提供的工具都通過一個單獨的命令`go`調用,`go`命令有一繫列子命令。最簡單的一個子命令就是run。這個命令編譯一個或多個以.go結尾的源文件, 鏈接庫文件, 併運行最終生成的可執行文件。( 本書使用$表示命令行提示符。)
2015-12-09 07:45:11 +00:00
```
$ go run helloworld.go
```
2015-12-22 02:37:13 +00:00
2015-12-26 12:05:30 +00:00
毫無意外,這個命令會輸出:
2015-12-22 02:37:13 +00:00
2015-12-09 07:45:11 +00:00
```
2015-12-22 02:37:13 +00:00
Hello, 世界
2015-12-09 07:45:11 +00:00
```
2016-01-19 15:19:32 +00:00
Go語言原生支持Unicode, 它可以處理全世界任何語言的文本。
2015-12-09 07:45:11 +00:00
2016-01-19 15:19:32 +00:00
如果不隻是一次性實驗, 你肯定希望能夠編譯這個程序, 保存編譯結果以備將來之用。可以用build子命令:
2015-12-22 02:37:13 +00:00
2015-12-09 07:45:11 +00:00
```
$ go build helloworld.go
```
2016-01-19 15:19:32 +00:00
這個命令生成一個名爲helloworld的可執行的二進製文件( 譯註: 在Windows繫統下生成的可執行文件是helloworld.exe, 增加了.exe後綴名) , 之後你可以隨時運行它, 不需任何處理( 譯註: 因爲是靜態編譯, 所以也不用擔心在繫統庫更新的時候衝突, 幸福感滿滿) 。
2015-12-22 02:37:13 +00:00
2015-12-09 07:45:11 +00:00
```
$ ./helloworld
2015-12-22 02:37:13 +00:00
Hello, 世界
2015-12-09 07:45:11 +00:00
```
2016-01-19 15:19:32 +00:00
( 譯註: 在Windows繫統下在命令行直接輸入helloworld.exe命令運行) :
2015-12-09 07:45:11 +00:00
2016-01-19 17:07:16 +00:00
本書中, 所有的示例代碼上都有一行標記,利用這些標記, 可以從[gopl.io](http://gopl.io)網站上本書源碼倉庫里獲取代碼:
2015-12-09 07:45:11 +00:00
2015-12-22 02:37:13 +00:00
```
gopl.io/ch1/helloworld
```
2015-12-09 07:45:11 +00:00
2016-01-19 15:19:32 +00:00
執行 `go get gopl.io/ch1/helloworld` 命令, 就會從網上獲取代碼( 譯註: 需要先安裝Git或Hg之類的版本管理工具, 併將對應的命令添加到PATH環境變量中) , 併放到對應目録中( 譯註: 序言已經提及, 需要先設置好GOPATH環境變量, 下載的代碼會放在 $GOPATH/src/gopl.io/ch1/helloworld 目録) 。2.6和10.7節有這方面更詳細的介紹。
2015-12-09 07:45:11 +00:00
2016-01-19 15:19:32 +00:00
來討論下程序本身。Go語言的代碼通過**包**( package) 組織, 包類似於其它語言里的庫( libraries) 或者模塊( modules) 。一個包由位於單個目録下的一個或多個.go源代碼文件組成, 目録定義包的作用。每個源文件都以一條`package`聲明語句開始,這個例子里就是`package main`, 表示該文件屬於哪個包, 緊跟着一繫列導入( import) 的包, 之後是存儲在這個文件里的程序語句。
2015-12-09 07:45:11 +00:00
2016-01-19 15:19:32 +00:00
Go的標準庫提供了100多個包, 以支持常見功能, 如輸入、輸出、排序以及文本處理。比如`fmt`包,就含有格式化輸出、接收輸入的函數。`Println`是其中一個基礎函數,可以打印以空格間隔的一個或多個值,併在最後添加一個換行符,從而輸出一整行。
2015-12-09 07:45:11 +00:00
2016-01-19 15:19:32 +00:00
`main` 包比較特殊。它定義了一個獨立可執行的程序,而不是一個庫。在`main`里的`main` *函數* 也很特殊, 它是整個程序執行時的入口( 譯註: 其實C繫語言差不多都是這樣) 。`main`函數所做的事情就是程序做的。當然了,`main`函數一般調用其它包里的函數完成很多工作, 比如`fmt.Println`。
2015-12-09 07:45:11 +00:00
2016-01-19 15:19:32 +00:00
必須告訴編譯器源文件需要哪些包,這就是`import`聲明以及隨後的`package`聲明扮演的角色。hello world例子隻用到了一個包, 大多數程序需要導入多個包。
2015-12-09 07:45:11 +00:00
2016-01-19 15:19:32 +00:00
必須恰當導入需要的包, 缺少了必要的包或者導入了不需要的包, 程序都無法編譯通過。這項嚴格要求避免了程序開發過程中引入未使用的包。( 譯註: Go語言編譯過程沒有警告信息, 爭議特性之一) 。
2015-12-09 07:45:11 +00:00
2016-01-19 15:19:32 +00:00
`import` 聲明必須跟在文件的`package`聲明之後。隨後,則是組成程序的函數、變量、常量、類型的聲明語句(分别由關鍵字`func`, `var` , `const` , `type` 定義)。這些內容的聲明順序併不重要。(譯註:最好還是定一下規范)。這個例子的程序已經盡可能短了,隻聲明了一個函數, 其中隻調用了一個其他函數。爲了節省篇幅,有些時候, 示例程序會省略`package`和`import`聲明,但是,這些聲明在源代碼里有,併且必須得有才能編譯。
2015-12-09 07:45:11 +00:00
2016-01-19 15:19:32 +00:00
一個函數的聲明由`func`關鍵字、函數名、參數列表、返迴值列表(這個例子里的`main`函數參數列表和返迴值都是空的)以及包含在大括號里的函數體組成。第五章進一步考察函數。
2015-12-09 07:45:11 +00:00
2016-01-20 04:47:32 +00:00
Go語言不需要在語句或者聲明的末尾添加分號, 除非一行上有多條語句。實際上, 編譯器會主動把特定符號後的換行符轉換爲分號, 因此換行符添加的位置會影響Go代碼的正確解析。( 譯註: 比如行末是, 一個標識符、一個整數、浮點數、虛數、字符或字符串文字、關鍵字break、continue、fallthrough或return中的一個、運算符和分隔符++、--、)、]或}中的一個)。舉個例子, 函數的左括號`{`必須和`func`函數聲明在同一行上, 且位於末尾,不能獨占一行,而在表達式`x + y`中,可在`+`後換行,不能在`+`前換行(譯註:以+結尾的話不會被插入分號分隔符, 但是以x結尾的話則會被分號分隔符, 從而導致編譯錯誤) 。
2015-12-09 07:45:11 +00:00
2016-01-19 17:07:16 +00:00
Go語言在代碼格式上采取了很強硬的態度。`gofmt`工具把代碼格式化爲標準格式( 譯註: 這個格式化工具沒有任何可以調整代碼格式的參數, Go語言就是這麽任性) , 併且`go`工具中的`fmt`子命令會對指定包, 否則默認爲當前目録, 中所有.go源文件應用`gofmt`命令。本書中的所有代碼都被gofmt過。你也應該養成格式化自己的代碼的習慣。以法令方式規定標準的代碼格式可以避免無盡的無意義的瑣碎爭執( 譯註: 也導致了Go語言的TIOBE排名較低, 因爲缺少撕逼的話題) 。更重要的是, 這樣可以做多種自動源碼轉換, 如果放任Go語言代碼格式, 這些轉換就不大可能了。
2015-12-09 07:45:11 +00:00
2016-01-19 15:19:32 +00:00
很多文本編輯器都可以配置爲保存文件時自動執行`gofmt`,這樣你的源代碼總會被恰當地格式化。還有個相關的工具,`goimports`,可以根據代碼需要, 自動地添加或刪除`import`聲明。這個工具併沒有包含在標準的分發包中,可以用下面的命令安裝:
2015-12-09 07:45:11 +00:00
```
$ go get golang.org/x/tools/cmd/goimports
```
2016-01-19 15:19:32 +00:00
對於大多數用戶來説, 下載、編譯包、運行測試用例、察看Go語言的文檔等等常用功能都可以用go的工具完成。10.7節詳細介紹這些知識。
2015-12-09 07:45:11 +00:00