2014-04-30 51 views
3

使用範圍A範圍內的信道Golang夠程沒有運行與功能推遲,關於信道

for s := range cs { 
    fmt.Println("Recieved Cake: ", s) 
} 

上應該保持功能打開,直到信道關閉,在該點的功能/夠程應該終止。當函數終止時,延遲函數應該在之前運行。這似乎並非如此,我找不到任何原因。

http://play.golang.org/p/ADu1MzAe9P上的示例代碼會生成延遲語句,除了從通道接收的函數外,其他語句的預期結果與預期相同。爲什麼會這樣呢?謝謝!

回答

5

延遲功能未執行的原因是應用程序到達main函數的末尾,導致整個程序終止而不等待goroutine。

Go Specification說:

當主函數返回,程序退出。它不會等待其他(非主要)goroutines完成。

由於您的recieveCakeAndPack仍在等待通道關閉(從不發生),所以在程序終止之前它永遠不會延遲。

編輯

在一個側面說明 - 把延遲聲明最後一個函數是沒有意義的。而是把它們直接放在會後聲明要推遲如:

fmt.Println("Entering function") 
defer fmt.Println("Leaving function") 

file, err := os.Open("file.txt") 
if err != nil { 
    return err 
} 
defer file.Close() 

的延遲在最後入先離開功能時,函數/方法調用將被執行出單。

+0

感謝關於放置推遲語句的提示,我曾在最後一刻匆匆拋出它們進行實驗,但對於放置位置你是絕對正確的。我所關心的主要問題是函數永遠不會返回(因爲我從來沒有關閉過這個通道!),現在看起來很明顯,你指出任何一個函數都不知道數據的長度或範圍,但我以某種方式假設它奇蹟般地知道。我使用固定延期和頻道關閉更新了示例,網址爲http://play.golang.org/p/nuQ2BktQM4,一切正常,正如我所期望的那樣。謝謝 – bertabus