超時對於連線到外部資源或在不需要繫結執行時間的程式很重要。在Go程式設計中由於使用了通道和選擇(select),實現超時是容易和優雅的。
在這個範例中,假設正在執行一個外部呼叫,2
秒後在通道c1
上返回其結果。
這裡是 select
實現超時。 res:= <-c1
等待結果和<-Time
。等待在超時1
秒後傳送一個值。 由於選擇繼續準備好第一個接收,如果操作超過允許的1
秒,則將按超時情況處理。
如果允許更長的超時,如:3s
,那麼從c2
的接收將成功,這裡將會列印結果。
執行此程式顯示第一個操作超時和第二個操作超時。
使用此選擇超時模式需要通過通道傳達結果。這是一個好主意,因為其他重要的Go
功能是基於渠道和Select
。現在看看下面的兩個例子:計時器和ticker
。
所有的範例程式碼,都放在
F:\worksp\golang
目錄下。安裝Go程式設計環境請參考:/2/23/798.html
timeouts.go
的完整程式碼如下所示 -
package main
import "time"
import "fmt"
func main() {
// For our example, suppose we're executing an external
// call that returns its result on a channel `c1`
// after 2s.
c1 := make(chan string, 1)
go func() {
time.Sleep(time.Second * 2)
c1 <- "result 1"
}()
// Here's the `select` implementing a timeout.
// `res := <-c1` awaits the result and `<-Time.After`
// awaits a value to be sent after the timeout of
// 1s. Since `select` proceeds with the first
// receive that's ready, we'll take the timeout case
// if the operation takes more than the allowed 1s.
select {
case res := <-c1:
fmt.Println(res)
case <-time.After(time.Second * 1):
fmt.Println("timeout 1")
}
// If we allow a longer timeout of 3s, then the receive
// from `c2` will succeed and we'll print the result.
c2 := make(chan string, 1)
go func() {
time.Sleep(time.Second * 2)
c2 <- "result 2"
}()
select {
case res := <-c2:
fmt.Println(res)
case <-time.After(time.Second * 3):
fmt.Println("timeout 2")
}
}
執行上面程式碼,將得到以下輸出結果 -
F:\worksp\golang>go run timeouts.go
timeout 1
result 2