2015-01-05 66 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

相關問題