什么是`if`语句的返回类型

时间:2013-05-08 09:18:04

标签: scala

从Scala编程书中我读到,在下面的代码中configFilePath常量将是Unit的类型:

scala> val configFilePath = if (configFile.exists()) {
| configFile.getAbsolutePath()
| }
configFilePath: Unit = ()

但是当我在REPL中执行此代码时,我得到类型为Any的结果。为什么?

书籍示例使用Scala 2.8,我使用Scala 2.10。

3 个答案:

答案 0 :(得分:7)

if (cond) { expr }返回Unit的公共基本类型和expr的类型,就像if (cond) { expr } else { () }一样。

AnyValIntCharUnitUnitAnyAnyRef

scala> if ( false ) 1
res0: AnyVal = ()

scala> val r = if ( false ) { () }
r: Unit = ()

scala> if ( false ) ""
res1: Any = ()

答案 1 :(得分:1)

与往常一样,if语句评估逻辑条件并且必须返回逻辑结果。因此:scala.Boolean。但价值并不是每个return。评估结果用于执行,但正如您所做的那样:

val configFilePath = if (configFile.exists()) {
    configFile.getAbsolutePath();// say this returns a String.
};

但如果configFile.exists()返回false怎么办?没有任何内容放在该变量中,因此编译器会将类型推断为Any,这是有道理的,因为您无法结束type

此外,您最好使用match

val configFilePath = configFile.exists match {
    case true => Some { configFile.getAbsolutePath }
    case false => None
};

以上是确定性的,应该返回Option[ReturnType],这是处理此类事情的默认Scala方式。

答案 2 :(得分:1)

if语句采用语句/闭包/变量。使用闭包时,最终语句用于推断类型。由于configFile.getAbsolutePath()是评估String的函数。 Unit子类Any表示以下任一工作:

val configFilePath:Any = if (configFile.exists()) {configFile.getAbsolutePath()}

val configFilePath:Unit = if (configFile.exists()) {configFile.getAbsolutePath()}

修改

案例可能是条件正在评估为假,例如

val map = Map(1 -> "1")
val result = if(map.get(2)=="1") "Whoopie!"

此处的结果将是Any = ()类型,因为没有else且值不是 存在或该值不等于1 如果您希望类型为String

,这将更合适
val configFilePath = if (configFile.exists()) {configFile.getAbsolutePath()} else ""