Typesafe Swing事件 – “在运行时无法检查此类型测试中的外部引
我正在实现一个Swing组件,我想克服Reactor的####无类型.所以我以为这样会工作:
trait Foo[A] extends scala.swing.Publisher { final case class Bar(parent: Vector[A],children: A*) extends scala.swing.event.Event } trait Test { val foo: Foo[Int] foo.reactions += { case foo.Bar(parent,children) => { println(parent.sum - children) } } } 不幸的是,给我两个编译器警告: The outer reference in this type test cannot be checked at run time. final case class Bar(parent: Vector[A],children: A*) extends scala.swing.event.Event ^ The outer reference in this type test cannot be checked at run time. case foo.Bar(parent,children) => { ^ 我应该忽略这些警告吗?我可以压制他们吗?我应该改变设计吗? 解决方法
在Scala中,内部类是“路径依赖”.
我将以你的代码为例.如果你有两个Foo [Int],称为foo和bar,那么foo.Bar是一个不同于bar.Bar的类型.请注意,这与Java的内部类的想法不同,其中foo.Bar和bar.Bar是相同的类型. 在任何情况下,JVM不直接支持内部类,所以在Java和Scala中,类Bar将编译为名为Foo $Bar的JVM类.内部类的实例几乎总是包含对其所有者的引用 – “外部引用”. 现在,当您在路径依赖类型(如代码中的一个)中有一个模式匹配时,Scala编译器将产生一个字符串,它有两件事情:它将检查该类(因此它将检查它接收到的对象是Foo $Bar的一个实例),它将检查外部引用(因此它将检查接收到的对象的外部引用是否为foo). 但是,在你的代码中,编译器找不到一个检查外部引用的方式,因为你已经将内部类定义为final. 所以,如果忽略该警告,那么你的模式将匹配所有Foo $Bar的实例,即使它们不属于foo.你会有一个比我更好的想法,这是否会是一个问题. 或者,您可以通过使内部课程非最终进行修复. Ps,我不完全确定为什么Scala编译器无法检查最终内部类的外部引用,但是我发现如果一个内部类是final,那么外部的$是private,而如果它是非final的$是公开的编译器的内部组件可能值得一试,找出原因. 更新 事实证明这是一个已知的问题 – SI-4440.如果Scala编译器没有被使用(这是模糊的合法的,因为没有子类也可能使用它们),Scala编译器会丢弃最终内部类的外部引用.一个积极的后果是外部类可以被垃圾收集,而内部类仍在使用,所以Scala开发人员不愿重新引入外部引用,因为担心引入内存泄漏. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |