写这样的东西有区别吗:
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)
谢谢!
第一个例子不是有效的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!在递归循环函数中使用会泄漏内存.