package main
import (
"fmt"
"time"
"math/rand"
"strconv"
)
func main(){
timeout := make(chan int, 1)
userChan := make(chan string, 1)
quitChan := make(chan int, 1)
var userAnswerStr string
var answer int
var a, b int
rand.Seed(time.Now().UTC().UnixNano())
timeoutFunc := func(quit chan int){
timeoutChan := make(chan int, 1)
go func(){
time.Sleep(5 * time.Second)
timeoutChan <- 1
}()
select{
case <-quit:
return
case <- timeoutChan:
timeout <- 1
}
}
inputFunc := func(){
var input string
_, err := fmt.Scanf("%s", &input)
if err != nil{
}
userChan <- input
}
go inputFunc()
for{
a = rand.Int() % 100
b = rand.Int() % 100
answer = a + b
fmt.Printf("%d + %d = %d\n", a, b, answer)
go timeoutFunc(quitChan)
select{
case userAnswerStr =<- userChan:
userAnswer, err := strconv.Atoi(userAnswerStr)
if err != nil{
fmt.Println("Error")
fmt.Printf("Input is %s\n", userAnswerStr)
}else{
if userAnswer == answer{
fmt.Println("yes\n")
}else{
fmt.Println("no\n")
}
}
go inputFunc()
quitChan <- 1
case <- timeout:
fmt.Println("timeout")
}
}
}
go 這個關鍵字後面接一個 statement。表示開一個新的 Goroutines (可以達到 thread 的功能), chan 就類似 queue。select 敘述則會等待,直到有個 chan 有東西,則繼續執行。想知道確切的用法,請參考 http://golang.org/doc/effective_go.html
golang 支援 closures,也可以讓程式變簡潔。不必還要傳參數進去,也減少暴露沒必要的函數。不過現在很多程式語言都支援 closures 就是了, python, ruby, javascript等語言。
沒有留言:
張貼留言