从Scala编程书中我读到,在下面的代码中configFilePath
常量将是Unit
的类型:
scala> val configFilePath = if (configFile.exists()) {
| configFile.getAbsolutePath()
| }
configFilePath: Unit = ()
但是当我在REPL中执行此代码时,我得到类型为Any
的结果。为什么?
书籍示例使用Scala 2.8,我使用Scala 2.10。
答案 0 :(得分:7)
if (cond) { expr }
返回Unit
的公共基本类型和expr
的类型,就像if (cond) { expr } else { () }
一样。
AnyVal
,Int
等Char
,Unit
为Unit
,Any
为AnyRef
:
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 ""