Go語言要點
控制流:在本章我們只介紹了if控制和for,但是沒有提到switch多路選擇。這裡是一個簡單的switch的例子:
switch coinflip() { case "heads": heads++ case "tails": tails++ default: fmt.Println("landed on edge!") }
在翻轉硬幣的時候,例子裡的coinflip函式返回幾種不同的結果,每一個case都會對應一個返回結果,這裡需要注意,Go語言並不需要顯式地在每一個case後寫break,語言預設執行完case後的邏輯語句會自動退出。當然了,如果你想要相鄰的幾個case都執行同一邏輯的話,需要自己顯式地寫上一個fallthrough語句來覆蓋這種預設行為。不過fallthrough語句在一般的程式中很少用到。
Go語言裡的switch還可以不帶操作物件(譯註:switch不帶操作物件時預設用true值代替,然後將每個case的表示式和true值進行比較);可以直接羅列多種條件,像其它語言裡面的多個if else一樣,下面是一個例子:
func Signum(x int) int { switch { case x > 0: return +1 default: return 0 case x < 0: return -1 } }
這種形式叫做無tag switch(tagless switch);這和switch true是等價的。
像for和if控制語句一樣,switch也可以緊跟一個簡短的變數宣告,一個自增表示式、賦值語句,或者一個函式呼叫(譯註:比其它語言豐富)。
break和continue語句會改變控制流。和其它語言中的break和continue一樣,break會中斷當前的迴圈,並開始執行迴圈之後的內容,而continue會跳過當前迴圈,並開始執行下一次迴圈。這兩個語句除了可以控制for迴圈,還可以用來控制switch和select語句(之後會講到),在1.3節中我們看到,continue會跳過內層的迴圈,如果我們想跳過的是更外層的迴圈的話,我們可以在相應的位置加上label,這樣break和continue就可以根據我們的想法來continue和break任意迴圈。這看起來甚至有點像goto語句的作用了。當然,一般程式設計師也不會用到這種操作。這兩種行為更多地被用到機器生成的程式碼中。
命名型別:型別宣告使得我們可以很方便地給一個特殊型別一個名字。因為struct型別宣告通常非常地長,所以我們總要給這種struct取一個名字。本章中就有這樣一個例子,二維點型別:
type Point struct { X, Y int } var p Point
型別宣告和命名型別會在第二章中介紹。
指標:Go語言提供了指標。指標是一種直接儲存了變數的記憶體地址的資料型別。在其它語言中,比如C語言,指標操作是完全不受約束的。在另外一些語言中,指標一般被處理為“引用”,除了到處傳遞這些指標之外,並不能對這些指標做太多事情。Go語言在這兩種範圍中取了一種平衡。指標是可見的記憶體地址,&操作符可以返回一個變數的記憶體地址,並且*操作符可以獲取指標指向的變數內容,但是在Go語言裡沒有指標運算,也就是不能像c語言裡可以對指標進行加或減操作。我們會在2.3.2中進行詳細介紹。
方法和介面:方法是和命名型別關聯的一類函式。Go語言裡比較特殊的是方法可以被關聯到任意一種命名型別。在第六章我們會詳細地講方法。介面是一種抽象型別,這種型別可以讓我們以同樣的方式來處理不同的固有型別,不用關心它們的具體實現,而只需要關注它們提供的方法。第七章中會詳細說明這些內容。
包(packages):Go語言提供了一些很好用的package,並且這些package是可以擴充套件的。Go語言社群已經創造並且分享了很多很多。所以Go語言程式設計大多數情況下就是用已有的package來寫我們自己的程式碼。通過這本書,我們會講解一些重要的標準庫內的package,但是還是有很多限於篇幅沒有去說明,因為我們沒法在這樣的厚度的書裡去做一部程式碼大全。
在你開始寫一個新程式之前,最好先去檢查一下是不是已經有了現成的庫可以幫助你更高效地完成這件事情。你可以在https://golang.org/pkg 和https://godoc.org 中找到標準庫和社群寫的package。godoc這個工具可以讓你直接在本地命令列閱讀標準庫的文件。比如下面這個例子。
$ go doc http.ListenAndServe package http // import "net/http" func ListenAndServe(addr string, handler Handler) error ListenAndServe listens on the TCP network address addr and then calls Serve with handler to handle requests on incoming connections. ...
註釋:我們之前已經提到過了在原始檔的開頭寫的註釋是這個原始檔的文件。在每一個函式之前寫一個說明函式行為的註釋也是一個好習慣。這些慣例很重要,因為這些內容會被像godoc這樣的工具檢測到,並且在執行命令時顯示這些註釋。具體可以參考10.7.4。
多行註釋可以用/* ... */
來包裹,和其它大多數語言一樣。在檔案一開頭的註釋一般都是這種形式,或者一大段的解釋性的註釋文字也會被這符號包住,來避免每一行都需要加//。在註釋中//和/*是沒什麼意義的,所以不要在註釋中再嵌入註釋。