2015-10-15 85 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编译,我会这样做。 –