2015-10-15 68 views
8

類型檢查我有簡單的類型層次斯卡拉:誤區與斯卡拉

trait A { 
    trait A1 
} 

object B extends A { 
    case object B1 extends A1 
} 

object C extends A { 
    case object C1 extends A1 
} 

而且,我會使用這些類型這樣的:

def get(): Any = C.C1 

get() match { 
    case _: B.A1 => println("B") 
    case _: C.A1 => println("C") 
    case _: A#A1 => println("Any") 
} 

出人意料的是,我越來越B印刷(我期望C)。

爲什麼編譯器將C.C1作爲B.A1的實例?

+0

我想這是類型擦除的問題,嘗試'scalac -Xprint:erasure',你的模式匹配被編譯成'A.A1' –

+0

@佐爾坦HTTP://www.scala- lang.org/files/archive/spec/2.11/03-types.html#equivalence –

+0

@HerringtonDarkholme我不認爲這些是[複合類型](http://www.scala-lang.org/old/node/ 110),但[路徑依賴類型](http://stackoverflow.com/questions/5581836/why-does-scala-have-path-dependent-types)。無論如何,我的假設是錯誤的。 –

回答

5

這是一個已知的錯誤。

Scalac 確實生成此警告使用-unchecked標誌:

warning: The outer reference in this type test cannot be checked at run time. 
      case _: B.A1 => println("B") 
       ^

所以現在,B.A1C.A1出現同樣在模式匹配的編譯器,因爲它不檢查外部參照BC

看到這個related discussion

而且SI-4440

+0

它看起來像編譯器中的錯誤。我想過,但決定我錯過了一些東西。我非常喜歡Scala,並希望這個問題將在未來的版本中得到解決。 –

+0

雖然,我沒有設法得到這個警告,而玩'-unchecked'標誌。試過斯卡拉2.10.5和2.11.7。 –

+0

我沒有在REPL中獲得它,但是如果我將相同的代碼放在scala文件中並使用scalac編譯,我會這樣做。 –