0

在使用 F# 团队博客文章测试 F# 尾调用时,我发现几乎相同的代码具有相同的结果,但IL不同,尽管代码中只有括号不同。

下一个代码由编译器优化,我br.s IL_0000在 IL 末尾看到并且没有调用sumSoFar

let rec loopAndSum aList sumSoFar = 
    match aList with
    | [] -> sumSoFar
    | x :: xs -> 
        loopAndSum xs (sumSoFar + x)

loopAndSum [ 1..5 ] 0 
|> printfn "sum: %i"

但是那部分没有被编译器优化,它已经call bla_bla.loopAndSum接近 IL 的结尾。

let rec loopAndSum aList sumSoFar = 
    match aList with
    | [] -> sumSoFar
    | x :: xs -> 
        loopAndSum xs sumSoFar + x

loopAndSum [ 1..5 ] 0 
|> printfn "sum: %i"

这些示例的不同之处仅在于 . 周围的括号sumSoFar + x您可以使用它并在.NET Fiddle上查看 IL 。

有人知道为什么括号很重要吗?

4

1 回答 1

4

函数应用的优先级高于任何运算符。所以没有括号,它相当于:

(loopAndSum xs sumSoFar) + x

因此它不是尾调用:加法是在递归调用之后执行的。结果值正确只是偶然。

于 2015-03-07T20:08:43.327 回答