gopl-zh.github.com/ch1/ch1-01.md

77 lines
6.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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