问题描述
据我了解, @specialized
注解应该为我提到的每种基本类型生成一些unboxed代码,但这不起作用:
scala> def aaa [@specialized(Int,Double,Float,Long)T] =(5.0).doubleValue.asInstanceOf [T]
aaa:[T] => T
scala> aaa [Int]
不可恢复的错误(解释器/编译器内)
p>
scala> def aaa [@specialized(Int,Double,Float,Long)T](a:T)=(5.0).doubleValue.asInstanceOf [T]
aaa:[T] => T
scala> aaa [Int](0)
ClassCastException
但它仍然使用盒装类型asInstanceOf [ T]。这显然有效:
scala> (5.0).asInstanceOf [Int]
res28:Int = 5
更新:
键入擦除和类似的答案没有任何东西处理我的问题。类型擦除只是防止编译器为泛型添加 typecast
字节码操作,但最终会添加 - 请参阅 ClassCastException
(由此操作生成)在我的REPL中
该方法是专门化的,但在单独编译(即不同的行)下,
在下面的例子中, bBf
可以工作, cBf
已损坏。
$ scala -Xprint:typer,cleanup
阶> :pa -raw
//进入粘贴模式(ctrl-D完成)
package a {object A {def aaa [@specialized(Int)T] =(5.0).doubleValue .asInstanceOf [T]}}
package b {object B {def f = aAaaa [Int]}}
//退出粘贴模式,现在解释。
[[typer结尾的语法树]] //< pastie>
包<空> {
package a {
object A extends scala.AnyRef {
def< init>():a.A.type = {
A.super。< init>();
()
};
def aaa [@specialized(scala.Int)T]:T = scala.this.Predef.double2Double(5.0).doubleValue()。asInstanceOf [T]
}
};
package b {
object B extends scala.AnyRef {
def< init>():b.B.type = {
B.super。< init>();
()
};
def f:Int = aAaaa [Int]
}
}
}
[[清理结束时的语法树]] //< ; pastie>
包<空> {
package a {
object A extends object {
def aaa():Object = scala.Double.box(scala.this.Predef.double2Double(5.0).doubleValue());
<专业> def aaa $ mIc $ sp():Int = scala.this.Predef.double2Double(5.0).doubleValue()。toInt();
def< init>():a.A.type = {
A.super。< init>();
()
}
}
};
package b {
object B extends Object {
def f():Int = a.A.aaa $ mIc $ sp();
def< init>():b.B.type = {
B.super。< init>();
()
}
}
}
}
scala> :pa -raw
//进入粘贴模式(ctrl-D完成)
package c {object B {def f = aAaaa [Int]}}
//退出粘贴模式,现在解释。
[[typer结尾的语法树]] //< pastie>
package c {
object B extends scala.AnyRef {
def< init>():c.B.type = {
B.super。< init>();
()
};
def f:Int = a.A.aaa [Int]
}
}
[[清理结束时的语法树]] //< pastie>
package c {
object B extends Object {
def f():Int = scala.Int.unbox(a.A.aaa());
def< init>():c.B.type = {
B.super。< init>();
()
}
}
}
As far as i understand, @specialized
annotation should generate some unboxed code for every primitive type i mentioned, but this doesn't work:
scala> def aaa[@specialized(Int, Double, Float, Long) T] = (5.0).doubleValue.asInstanceOf[T]
aaa: [T]=> T
scala> aaa[Int]
unrecoverable error (inside interpreter/compiler)
This compiles:
scala> def aaa[@specialized(Int, Double, Float, Long) T](a: T) = (5.0).doubleValue.asInstanceOf[T]
aaa: [T]=> T
scala> aaa[Int](0)
ClassCastException
But it still uses boxed type for asInstanceOf[T]. This obviously works:
scala> (5.0).asInstanceOf[Int]
res28: Int = 5
UPDATE: Type erasure and answers like that Writing a generic cast function Scala has nothing to do with my problem. Type erasure just preventing compiler from adding typecast
byte-code operation for generics, but eventually it will be added - see ClassCastException
(generated by this op) in my REPL
The method is specialized, but under separate compilation (i.e., different lines), the specialized method isn't invoked.
In the following, b.B.f
works, c.B.f
is broken.
$ scala -Xprint:typer,cleanup
scala> :pa -raw
// Entering paste mode (ctrl-D to finish)
package a { object A { def aaa[@specialized(Int) T] = (5.0).doubleValue.asInstanceOf[T] }}
package b { object B { def f = a.A.aaa[Int] }}
// Exiting paste mode, now interpreting.
[[syntax trees at end of typer]] // <pastie>
package <empty> {
package a {
object A extends scala.AnyRef {
def <init>(): a.A.type = {
A.super.<init>();
()
};
def aaa[@specialized(scala.Int) T]: T = scala.this.Predef.double2Double(5.0).doubleValue().asInstanceOf[T]
}
};
package b {
object B extends scala.AnyRef {
def <init>(): b.B.type = {
B.super.<init>();
()
};
def f: Int = a.A.aaa[Int]
}
}
}
[[syntax trees at end of cleanup]] // <pastie>
package <empty> {
package a {
object A extends Object {
def aaa(): Object = scala.Double.box(scala.this.Predef.double2Double(5.0).doubleValue());
<specialized> def aaa$mIc$sp(): Int = scala.this.Predef.double2Double(5.0).doubleValue().toInt();
def <init>(): a.A.type = {
A.super.<init>();
()
}
}
};
package b {
object B extends Object {
def f(): Int = a.A.aaa$mIc$sp();
def <init>(): b.B.type = {
B.super.<init>();
()
}
}
}
}
scala> :pa -raw
// Entering paste mode (ctrl-D to finish)
package c { object B { def f = a.A.aaa[Int] }}
// Exiting paste mode, now interpreting.
[[syntax trees at end of typer]] // <pastie>
package c {
object B extends scala.AnyRef {
def <init>(): c.B.type = {
B.super.<init>();
()
};
def f: Int = a.A.aaa[Int]
}
}
[[syntax trees at end of cleanup]] // <pastie>
package c {
object B extends Object {
def f(): Int = scala.Int.unbox(a.A.aaa());
def <init>(): c.B.type = {
B.super.<init>();
()
}
}
}
这篇关于为什么@specialized注释不适用于asInstanceOf?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!