【发布时间】:2015-03-07 20:04:58
【问题描述】:
在与 F# 团队 blog article 测试 F# 尾调用时,我发现 几乎相同 代码具有相同的结果,但 不同 IL 虽然代码中只有括号不同。
下一个代码由编译器优化,我在 IL 末尾看到 br.s IL_0000 并且没有调用 sumSoFar
let rec loopAndSum aList sumSoFar =
match aList with
| [] -> sumSoFar
| x :: xs ->
loopAndSum xs (sumSoFar + x)
loopAndSum [ 1..5 ] 0
|> printfn "sum: %i"
但是该部分没有经过编译器优化,并且在 IL 末尾附近有 call bla_bla.loopAndSum。
let rec loopAndSum aList sumSoFar =
match aList with
| [] -> sumSoFar
| x :: xs ->
loopAndSum xs sumSoFar + x
loopAndSum [ 1..5 ] 0
|> printfn "sum: %i"
这些示例的不同之处仅在于 sumSoFar + x 周围的括号。
您可以使用它并查看 IL .NET Fiddle。
有人知道为什么括号很重要吗?
【问题讨论】:
-
你是否真的测试过他们是否做了同样的事情。第二个版本将始终将
sumSoFar设置为 0。 -
@JohnPalmer,两个版本都在 LinqPad 和小提琴中本地打印
sum: 15。 -
如果你每次打印
sumSoFar你会得到不同的结果。 -
@JohnPalmer,我发现不是。请在小提琴中编写示例。
标签: f# tail-recursion tail-call-optimization tail-call