F#异步 - 两个结构之间的差异

Dav*_*ier 5 f# asynchronous

写这样的东西有区别吗:

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

并写这样:

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

谢谢!

Tom*_*cek 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 []})
Run Code Online (Sandbox Code Playgroud)

您也可以将外部async { .. }块保留在代码段中 - 然后您只需要使用它return!来调用您的loop函数而不是仅仅返回它(但除此之外现在没有显着差异).

请注意,我使用return!而不是do!- 这实际上有所不同,因为return!表示尾调用,这意味着可以丢弃当前正文的其余部分.如果你使用do!那么async在堆中分配类似堆栈的东西,所以do!在递归循环函数中使用会泄漏内存.

  • 我不禁想知道他们为什么不先看它是否有效. (2认同)