2011-08-01 54 views
5

之間也是有差別的寫這樣的事情之間的差異:F#異步 - 二元結構

MailboxProcessor.Start(fun inbox -> async { 
    let rec loop bugs = 
     let! msg = inbox.Receive() 
     let res = //something 
     loop res 
    loop []}) 

而且這樣寫的:

MailboxProcessor.Start(fun inbox -> 
    let rec loop bugs = async { 
     let! msg = inbox.Receive() 
     let res = //something 
     do! loop res } 
    loop []) 

謝謝!

回答

7

第一個例子是無效的F#代碼,因爲let!只能在計算表達式中使用。在你的例子中,你在普通函數中使用它 - 它的主體不是一個計算表達式,所以let!不允許在那個位置。

要使其有效,你需要包裹loop功能的體內async

MailboxProcessor.Start(fun inbox -> async { 
    let rec loop bugs = async { 
     let! msg = inbox.Receive() 
     let res = //something 
     return! loop res } 
    return! loop []}) 

你可以保持在片段外async { .. }塊,以及 - 那麼你只需要使用return!打電話給你的loop函數,而不是僅僅返回它(但除此之外,現在沒有顯着差異)。我用return!代替do!

注 - 這實際上有差別,因爲return!表示尾部調用,這意味着當前的身體的其餘部分可以被丟棄。如果你使用do!那麼異步在堆中分配類似堆棧的東西,所以在遞歸循環函數中使用do!會泄漏內存。

+2

我不禁想知道爲什麼他們沒有看到它是否先工作。 – ChaosPandion

+1

在這裏,我想知道爲什麼當我回到家時,所有的應用程序都崩潰了,我的系統說虛擬內存! 感謝Tomas! –

+0

@ChaosPandion非常好的一點,我在玩代碼,因爲其他原因沒有編譯的代碼,只是假設我在看什麼會工作 - 隨意投票回答這個問題,但Tomas的答案非常有用。 –