我在一些Scala代码中犯了类似下面的错误:
val someVal:String = if (someX == someY) n
回想起来,这个错误对我很清楚(它必须为someVal分配一些内容,如果表达式为false,它可能不会是一个字符串)。我想知道如果表达式为false,返回的值是什么。我最好的猜测是单位,或者也许是AnyVal。
答案 0 :(得分:10)
该代码不会编译,因为someVal
是一个String,那么每个执行路径(if
和else
)都必须返回一个String。但是,由于你没有else
,这是不可能的,因而无法编译。
编译器错误将如下所示,表示当您应该返回Unit
时返回String
:
error: type mismatch;
found : Unit
required: String
那是因为你拥有的东西等同于:
val someVal: String = if (foo == bar) "Hello World" else ()
()
是Unit的唯一值,它不是String类型的有效值。
将来你可以使用Scala repl并让它告诉你类型(只是不指定一个):
scala> val someVal1 = if (true) "Hello World"
someVal1: Any = Hello World
val someVal2 = if (false) "Hello World"
someVal2: Any = ()
您可以看到类型为Any
,因为这是Unit
和String
之间唯一的共同父级:
答案 1 :(得分:2)
整个if表达式的类型将是所有分支的最小公共超类型。
您的示例中的真实路径为String
缺少的其他内容与空的其他内容相同,都评估为Unit
。
Unit
和String
位于完全独立的继承树中,(String为AnyRef
且Unit
为AnyVal
)因此整个表达式的类型为Any
,Scala中所有类型的常见超类型。
如果真实案例导致AnyVal
类型(例如Int
),则整个表达式的类型将为AnyVal
如果真实案例评估为Unit
(例如,如果你在if中使用了println
而不是返回一个值)那么表达式的类型将是Unit
因为两条路径都有相同的类型。