在嵌套在对象中的trait中混合时的AbstractMethodError - 仅在编译和导入时 [英] AbstractMethodError when mixing in trait nested in object - only when compiled and imported
问题描述
考虑以下代码:
object Impls {
trait ConcreteImpl {
type Foo = Int
def foo = 1
}
}
trait Base {
type Foo
def foo: Foo
}
我对表达式感兴趣
(new Base with Impls.ConcreteImpl).foo
当我粘贴时在REPL上面的代码,或者在工作表中运行它,然后尝试表达式 - 没问题,按预期打印 res0:Int = 1
。
When I paste the above code in the REPL, or run it in a worksheet, and then try the expression -- no problem, it prints res0: Int = 1
, as expected.
当我把代码放在一个文件中时,用 scalac
编译它,然后使用来自的编译后的类文件在同一目录中的REPL,我得到相同的结果。
When I put the code in a file, compile it with scalac
, and then use the compiled class files from the REPL in the same directory, I get the same result.
然而,当我使用编译的文件,然后从REPL说
However, when I use the compiled files, and then say from the REPL
import Impls._
(new Base with ConcreteImpl).foo
它抛出
java.lang.AbstractMethodError: $anon$1.foo()I
如果我将所有代码粘贴到REPL中,并使用导入变体,这 not 发生。
If I paste all code in the REPL, and use the import variant, this does not happen.
这里发生了什么?这甚至是预期的行为吗?如果相关,我正在使用
What is happening here? Is this even expected behaviour? If relevant, I am using
Scala version 2.11.5 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_45)
推荐答案
这显然是一个错误。
如果您:
java.lang.AbstractMethodError: $line13.$read$$iw$$iw$$iw$$iw$$iw$$iw$$anon$1.foo()I
... 33 elided
scala> :javap -p $line13.$read$$iw$$iw$$iw$$iw$$iw$$iw$$anon$1
Compiled from "<console>"
public final class $line13.$read$$iw$$iw$$iw$$iw$$iw$$iw$$anon$1 implements p.Base,p.Impls$ConcreteImpl {
public java.lang.Object foo();
public $line13.$read$$iw$$iw$$iw$$iw$$iw$$iw$$anon$1();
}
它没有结果类型为Int的foo。
It doesn't have a foo with result type Int.
副手,我无法想象REPL的差异,但我们即将看电影......不过你可以在Ammonite中尝试。
Offhand, I can't imagine the difference in the REPL, but we're about to watch a movie... You can try it in Ammonite, however.
大多数此类错误是由于REPL是驻留编译器这一事实,但是这对于如何影响现有类文件的编译并不明显。
Most such bugs are due to the fact that REPL is a resident compiler, but it's not obvious how that affects compilation with existing class files.
编辑:
它第一次使用完全限定名称,但在出现失败后,完全合格的失败了。
It works the first time using fully-qualified names, but then after exhibiting the failure, fully-qualified fails again.
scala> (new p.Base with p.Impls.ConcreteImpl).foo // show
//works
res0: Int = 1
scala> import p._
import p._
scala> import Impls._
import Impls._
scala> (new Base with ConcreteImpl).foo // show
// fails
java.lang.AbstractMethodError: $anon$1.foo()I
... 33 elided
scala> (new p.Base with p.Impls.ConcreteImpl).foo // show
// also fails
java.lang.AbstractMethodError: $anon$1.foo()I
... 33 elided
这显然是常驻编译器错误。 (这里的类在包中。)
That's clearly a resident compiler bug. (The classes are in package p here.)
编辑:实际上 SI-9689 。
这篇关于在嵌套在对象中的trait中混合时的AbstractMethodError - 仅在编译和导入时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!