Golang 語法速查(二)
1. 併發 (Concurrency)
Goroutines
go say("world") // 啟動一個新的 goroutine
Channels
ch := make(chan int) // 創建 channel
// 發送
go func() { ch <- 42 }()
// 接收
v := <-ch
// Buffered Channel
ch2 := make(chan int, 100)
// 關閉 Channel
close(ch)
// Range Channel
for i := range ch {
fmt.Println(i)
}
Select
select {
case c <- x:
x, y = y, x+y
case <-quit:
fmt.Println("quit")
default:
fmt.Println("waiting")
}
2. 錯誤處理 (Error Handling)
i, err := strconv.Atoi("42")
if err != nil {
fmt.Printf("couldn't convert number: %v\n", err)
return
}
fmt.Println("Converted integer:", i)
3. Defer
Go 的 defer 語句用於預設一個函數調用(即推遲執行函數),該函數會在執行 defer 的函數返回之前立即執行。它顯得非比尋常,但卻是處理一些事情的有效方式,例如無論以何種路徑返回,都必須釋放資源的場景。典型的例子就是解鎖互斥鎖和關閉文件。
Go's defer statement schedules a function call (the deferred function) to be run immediately before the function executing the defer returns. The canonical examples are unlocking a mutex or closing a file.
基本範例
func main() {
defer fmt.Println("world")
fmt.Println("hello")
}
// 輸出:
// hello
// world
典型用法:關閉文件
// Contents 將文件內容作為字串返回
func Contents(filename string) (string, error) {
f, err := os.Open(filename)
if err != nil {
return "", err
}
defer f.Close() // f.Close 會在函數結束時執行,無論從哪個 return 離開
var result []byte
buf := make([]byte, 100)
for {
n, err := f.Read(buf[0:])
result = append(result, buf[0:n]...)
if err != nil {
if err == io.EOF {
break
}
return "", err // 在這裡 return 時,f 也會 被關閉
}
}
return string(result), nil // 在這裡 return 時,f 也會被關閉
}
推遲 Close 的兩點好處: