写这样的东西之间是否有区别:
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 [])
谢谢!
答案 0 :(得分: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!
,那么async会在堆中分配类似堆栈帧的内容,因此在递归循环函数中使用do!
会泄漏内存。