3

如果我有以下功能:

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 ?

4

2 回答 2

9

值得补充的是,这不仅仅是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)
于 2013-05-10T20:39:42.067 回答
7

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

于 2013-05-10T17:27:32.267 回答