scala – 尽管有@specialized,但由于类型擦除导致重复的方法
偶然发现了
def foo(f: Int => Unit) {} def foo(f: Long => Unit) {} 因为方法foo定义了两次而没有编译.我知道上面只是一个简写 def foo(f: Function1[Int,Unit]) {} def foo(f: Function1[Long,Unit]) {} 并且在类型擦除之后,两种方法都具有相同的签名. 现在我已经在Try out specialized Function1/Function2 in 2.8.0 RC1!中读到,自Scala 2.8以来,Function1和Function2具有Int,Long和Double的@specialized版本.这肯定意味着Function [Int,Unit]和Function [Long,Unit]在JVM级别具有单独的类文件. 那么两个签名都不会有所不同吗? 问题是,第二种类型的参数会继续被删除吗?但同样的问题 class Bar[@specialized T] def foo(f: Bar[Int]) {} def foo(f: Bar[Long]) {} 它没有编译. 解决方法
@specialized与类型擦除无关,至少在这种情况下.这意味着将使用位置中的本机类型生成类的额外版本.这显着节省了装箱/拆箱.
所以你定义一个类,如: class MyClass[@specialized(Int) T] { def foobar(t: T) = {} } 并且你得到两个类作为输出,(大约): class Foobar[java.lang.Object] { def foobar(t: java.lang.Object) = {} } class Foobar[int] { def foobar(t: int) = {} } 您需要有两个类的实现,因为您不能总是保证将调用具有正确本机类型的实现. scala编译器将选择要调用的编译器.请注意,java编译器不知道这种特化正在发生,因此必须调用unspecialized方法. 实际上,输出如下(通过JAD): public class MyClass implements ScalaObject { public void foobar(Object obj) { } public void foobar$mcI$sp(int t) { foobar(BoxesRunTime.boxToInteger(t)); } public MyClass() { } } public class MyClass$mcI$sp extends MyClass { public void foobar(int t) { foobar$mcI$sp(t); } public void foobar$mcI$sp(int i) { } public volatile void foobar(Object t) { foobar(BoxesRunTime.unboxToInt(t)); } public MyClass$mcI$sp() {} } 所以你的类型擦除问题不会被@specialized修复. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |