main
。"math/rand"
包由 package rand 語句開始。import ( "fmt" "math/rand" )
在 Go 中,首字母大寫的名稱是被導出的。
函數可以沒有參數或接受多個參數。注意類型在變量名 之後。func add(x int, y int) int { return x + y }
當兩個或多個連續的函數命名參數是同一類型,則除了最後一個類型之外,其他都可以省略。x int, y int = x, y int
函數可以返回任意數量的返回值。
var 語句定義了一個變量的列表;如果初始化是使用表達式,則可以省略類型;變量從初始值中獲得類型。:=
簡潔賦值語句在明確類型的地方,可以用於替代 var 定義。
函數外的每個語句都必須以關鍵字開始(var
、func
、等等),:=
結構不能使用在函數外。
Go 的基本類型有Basic types
bool
string
int int8 int16 int32 int64
uint uint8 uint16 uint32 uint64 uintptr
byte // uint8 的別名
rune // int32 的別名
// 代表一個Unicode碼
float32 float64
complex64 complex128
變量在定義時沒有明確的初始化時會賦值為_零值_。數值類型為 0
,布爾類型為 false
,字符串為 ""
(空字符串)。
在定義一個變量但不指定其類型時(使用沒有類型的 var 或 := 語句), 變量的類型由右值推導得出。
常量不能使用 := 語法定義。
Go 只有一種循環結構——for
循環。
for i := 0; i < 10; i++ { sum += i }
可以讓前置、後置語句為空。for sum < 1000 { sum += sum }
如果省略了循環條件,循環就不會結束,因此可以用更簡潔地形式表達死循環。
if
語句可以在條件之前執行一個簡單的語句。
沒有條件的 switch
沒有條件的 switch 同 switch true
一樣。
這一構造使得可以用更清晰的形式來編寫長的 if-then-else 鏈。switch { case t.Hour() < 12: fmt.Println("Good morning!") case t.Hour() < 17: fmt.Println("Good afternoon.") default: fmt.Println("Good evening.") }
defer 語句會延遲函數的執行直到上層函數返回。延遲調用的參數會立刻生成,但是在上層函數返回前函數都不會被調用。延遲的函數調用被壓入一個棧中。當函數返回時, 會按照後進先出的順序調用被延遲的函數調用。
Go 具有指針。 指針保存了變量的內存地址。類型 T 是指向類型 T 的值的指針。其零值是 nil
。& 符號會生成一個指向其作用對象的指針。 符號表示指針指向的底層的值。
一個結構體(struct
)就是一個字段的集合。結構體字段使用點號來訪問。
結構體文法表示通過結構體字段的值作為列表來新分配一個結構體。使用 Name: 語法可以僅列出部分字段。(字段名的順序無關。)
數組的長度是其類型的一部分,因此數組不能改變大小。 這看起來是一個制約,但是請不要擔心; Go 提供了更加便利的方式來使用數組。
一個 slice 會指向一個序列的值,並且包含了長度信息。slice 可以重新切片,創建一個新的 slice 值指向相同的數組。
for 循環的 range 格式可以對 slice 或者 map 進行迭代循環。
map 在使用之前必須用 make 而不是 new 來創建;值為 nil 的 map 是空的,並且不能賦值。
如果頂級的類型只有類型名的話,可以在文法的元素中省略鍵名。
Go 函數可以是閉包的。閉包是一個函數值,它來自函數體的外部的變量引用。 函數可以對這個引用值進行訪問和賦值;換句話說這個函數被“綁定”在這個變量上。
Go 沒有類。然而,仍然可以在結構體類型上定義方法。方法接收者 出現在 func 關鍵字和方法名之間的參數中。
goroutine 是由 Go 運行時環境管理的輕量級線程。go f(x, y, z)
開啟一個新的 goroutine 執行f(x, y, z)
channel 是有類型的管道,可以用 channel 操作符 <- 對其發送或者接收值。
ch <- v // 將 v 送入 channel ch。
v := <-ch // 從 ch 接收,並且賦值給 v。
(“箭頭”就是數據流的方向。)
和 map 與 slice 一樣,channel 使用前必須創建:
ch := make(chan int)
默認情況下,在另一端准備好之前,發送和接收都會阻塞。這使得 goroutine 可以在沒有明確的鎖或競態變量的情況下進行同步。
channel 可以是 帶緩沖的。為 make 提供第二個參數作為緩沖長度來初始化一個緩沖 channel:
ch := make(chan int, 100)
channel 與文件不同;通常情況下無需關閉它們。只有在需要告訴接收者沒有更多的數據的時候才有必要進行關閉