2015-01-05 36 views
0
scala> def b(x:Int) = { x match { case 1 => 1; case 2 => 3.5; case k => throw new Exception("Nothing")}} 
b: (x: Int)AnyVal 
scala> def c(x: Int) = if (x == 1) 1 else if (x == 2) 3.5 else throw new Exception("Nothing") 
c: (x: Int)Double 

这是我从REPL获得的。为什么scala编译器将函数b的返回类型视为AnyVal。我认为,应该是Double。 任何指示都会有帮助。为什么Int,Double和Nothing的常见超级类型是AnyVal

+4

'双'不是'超'的超类型 - 它们之间最具体的常见超类型是'AnyVal'。 – Lee

+0

@这是真的,但是'Int'通常隐式转换为'Double'。在这种情况下,存在第三个“case”,它将抛出类型推断。 – Dima

+0

@迪玛,谢谢你的帮助!我仍然想知道为什么'throws'子句停止隐式将'Int'转换为'Double'? – davidyoulanda

回答

-1

如果您需要以这种方式对待它,您可以声明它为def b(x:Int): Double。 如果没有它,编译器会被throws子句弄糊涂,并推断错误类型。类型推断并不完美,有时你必须帮助神奇:)

4

Nothing的子类型,每类型(见Scaladoc)。这是必要的,以允许表达如

val x : Int = ??? 

IntDouble最小公用超类型是AnyValNothing,是任何东西的子类型(包括AnyVal),因此不会更改推断的类型。

+0

这在技术上是正确的,但有点误导:尽管Int和Double的常见超类型确实是AnyVal,但类型推断失败的原因是带有throw子句的第三个case。没有它,'Int'被隐含地转换为'Double',并且'Double'返回类型被正确推断。奇怪的是,用'3'代替'3.5'也会将推断类型改为'Int'。 – Dima

+0

最后一点并不令人意外 - 当然,“Int”,“Int”和“Nothing”的常见超类型是“Int”。 – lmm

+0

@misberner对不起,我没有清楚地陈述我的问题。当第三种情况被移除时,类型推断可以推断返回类型为'Double' – davidyoulanda

相关问题