3

从 Programming Scala 书中我读到,在以下代码中,configFilePath常量的类型为Unit

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

但是当我在 REPL 中执行这段代码时,我得到了 type 的结果Any。为什么?

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

4

3 回答 3

7

if (cond) { expr }返回公共基类型 ofUnit和 类型expr,就像if (cond) { expr } else { () }.

它是AnyValfor IntChar依此类推,UnitforUnitAnyfor AnyRef

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

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

scala> if ( false ) ""
res1: Any = ()
于 2013-05-08T09:29:29.230 回答
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 处理此类事情的默认方式。

于 2013-05-08T09:19:39.127 回答
1

if语句采用语句/闭包/变量。使用闭包时,final 语句用于推断类型。因为configFile.getAbsolutePath()是一个评估为 的函数StringUnit子类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 ""
于 2013-05-08T09:39:04.097 回答