在If表达式中返回类型

gge*_*kus 18 scala

我正在学习scala,无法理解为什么:

def signum(arg: Int) = {
    if(arg > 0 ) 1
    else if(arg < 0) -1
    else 0
}
Run Code Online (Sandbox Code Playgroud)

Int返回类型signum (arg: Int): Int

def signum(arg: Int) = {
    if(arg > 0 ) 1
    else if(arg < 0) -1
    else if(arg == 0) 0
}
Run Code Online (Sandbox Code Playgroud)

具有 AnyVal signum (arg: Int): AnyVal

ten*_*shi 24

这是因为在第二种情况下你没有指定最终else部分.在这种情况下,这个缺失分支的返回类型将是Unit.所以Scala编译器推断AnyVal,为一个共同的父IntUnit.

您可以尝试向函数签名添加显式返回类型:

def signum(arg: Int): Int = ...
Run Code Online (Sandbox Code Playgroud)

它不会编译以下错误:

 found   : Unit
 required: Int
    else if(arg == 0) 0
         ^
one error found
Run Code Online (Sandbox Code Playgroud)

所以编译器告诉你if实际的结果类型实际上Unit不是Int.

  • 向所有公共成员添加类型注释是一个非常好的主意.首先,它可以防止这样的错误.第二,它是一种文档.第三,有时你想要返回某个(通用)类型,但编译器会推断出最具体的类型,例如你想要_Seq_而不是_List_. (9认同)

Dan*_*ral 21

在没有明确的情况下else,Scala假设:

else ()
Run Code Online (Sandbox Code Playgroud)

()价值在哪里Unit?例如,它是由返回println或赋值的值var.

这很容易验证:

scala> val x = if (false) 1
x: AnyVal = ()

scala> x.isInstanceOf[Unit]
res3: Boolean = true
Run Code Online (Sandbox Code Playgroud)