如果我有以下功能:
let myFunc x y =
if y = 0 then 1
x
我收到错误:
Program.fs(58,17): error FS0001: This expression was expected to have type
unit
but here has type
int
为什么编译器期望'unit'而不是int?
答案 0 :(得分:9)
值得补充的是,这不仅仅是if
的属性。 F#是一种基于表达式的语言,意味着几乎每一段代码(除了类型声明和一些例外)都是一个表达式,它评估一些结果。事实上,F#不会调用if
if 语句,而是调用if 表达式。
这意味着您可以在意外的地方使用if
。例如,这可能很有用:
x/2 + (if x%2=0 then 0 else 1)
正如Garry已经解释的那样,如果省略else
,那么表达式仍然需要返回一些东西 - 如果结果是int
,那么它就没有意义(哪个数字)如果编译器选择?),那么它要求结果是unit
类型,这是一种表示“无结果”的特殊类型。
unit
类型也是所有命令函数(例如printf
)或所有不逻辑返回任何值(赋值或例如循环)的表达式的结果。这意味着如果你写:
if x > 0 then printfn "Big!"
...然后表达式是良好类型的,因为printfn "Big!"
具有返回类型unit
,并且隐式添加的else
分支也返回unit
。您可以直接手动创建类型unit
的值(类型只有一个值),因此上面实际上对应于:
if x > 0 then printfn "Big!" else ()
从C#的角度来看,将if .. then .. else
作为条件运算符更有意义:
x/2 + (x%2 == 0 ? 0 : 1)
答案 1 :(得分:7)
在F#中,当没有if
分支时使用else
语句时,它会隐式返回unit
。如果您的then
分支返回unit
以外的类型,则必须具有明确的else
分支才能使其正常工作。在你的例子中,你可以写:
let myFunc x y = if y = 0 then 1 else x
MSDN - http://msdn.microsoft.com/en-us/library/dd233231.aspx