F#,赋值运算符vs set运算符

时间:2013-04-10 11:24:22

标签: f#

我从F#开始,一些代码结构让我很惊讶。例如:

我有下一个代码:

let mutable s = 10
s <- 1 + s
printf "%i" s

数学方面的一切都很清楚。我将“s”标记为可变,并将新值分配给“s”。结果是11。

让我尝试代码的其他部分:

let mutable s = 10
s = 1 + s
printf "%i" s

此代码已经完成。但我发现s = 1 + s在数学方面有点奇怪。执行此结果是10.

我的问题,上一个样本中发生了什么?为什么我没有收到错误? s = 1 + s被忽略了吗?为什么?我没有在输出中出现任何错误。

2 个答案:

答案 0 :(得分:5)

代码

s=1+s

不会修改s - 等效的C#是

s==1+s

只返回false

实际上,编译器应该在该行上发出关于未使用值的警告。

=运算符只进行相等检查 - 分配任何值。

答案 1 :(得分:3)

回答你的第二个问题 -

  

为什么我没有收到错误? s = 1 + s被忽略了吗?为什么?我没有在输出中出现任何错误。

原因是F#区分脚本文件中的顶级作用域和本地作用域。当您处于脚本文件(Visual Studio中的*.fsx文件或Try F#内部)时,您可能希望编写一系列表达式(可能返回一个值)并逐个交互地执行它们。这意味着当您在一行上写s = 1 + s时,这不是错误,因为您可以评估该行(选择它并按Ctrl + Enter或Alt + Enter)并在交互式输出中查看结果。

但是,如果它出现在函数内(或其他本地范围中,您不希望以交互方式对其进行评估),则会收到警告。最简单的方法是使用do创建一个本地范围(这也适用于Try F#):

do
  let mutable s = 10
  s = 1 + s           // Warning: This expression should have type 'unit', 
                      //    but has type 'bool'. If assigning to a property 
                      //    use the syntax 'obj.Prop <- expr'.
  printf "%i" s