如果我有以下功能:
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 ?
如果我有以下功能:
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 ?
值得补充的是,这不仅仅是if
. F# 是一种基于表达式的语言,这意味着几乎每一段代码(除了类型声明和一些例外)都是一个计算结果的表达式。事实上,F# 调用if
的不是 if语句,而是一个 if表达式。
这意味着您可以if
在意想不到的地方使用。例如,这可能很有用:
x/2 + (if x%2=0 then 0 else 1)
正如 Garry 已经解释的那样,如果你省略else
,那么表达式仍然需要返回一些东西 - 如果结果是 an int
,那么它就没有意义(编译器应该选择哪个数字?),所以它需要结果是 type unit
,这是一种表示“无结果”的特殊类型。
该unit
类型也是所有命令式函数(例如printf
)或所有在逻辑上不返回任何值的表达式(赋值或例如循环)的结果。这意味着如果你写:
if x > 0 then printfn "Big!"
...然后表达式是类型良好的,因为printfn "Big!"
具有返回类型unit
并且隐式添加的else
分支也返回unit
。可以unit
直接手动创建类型的值(类型只有一个值),所以上面其实对应:
if x > 0 then printfn "Big!" else ()
if .. then .. else
从 C# 的角度来看,读取为条件运算符更有意义:
x/2 + (x%2 == 0 ? 0 : 1)
if
在 F# 中,当没有分支时使用语句时,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