从专门 class 中获取 ClassTag
Get ClassTag from within specialized class
当我有一个@specialized class 时,我会保留有关我的类型是什么基元的信息。有没有 fast 的方法来获得 ClassTag[T]
,例如创建数组?
这不会编译,因为没有可用的 ClassTag[T]
class Foo[@specialized T] {
def bar: Array[T] = new Array[T]
}
这可行,但我想避免传递 ClassTag
class Foo[@specialized T: ClassTag] {
def bar: Array[T] = new Array[T]
}
这有效,但速度很慢:
class Foo[@specialized T] {
def bar: Array[T] = new Array[T]
implicit def classTag: ClassTag[T] = {
val name = getClass.getName
if(name.endsWith("$I$sp") ClassTag.Int
else if(name.endsWith("$L$sp") ClassTag.Long
else ??? // you get the idea
}
}
专业化发生在打字机上 ClassTags 的具体化之后,所以这是谷仓门的问题。
另一个问题是特化会创建双重定义,因此以明显的方式手动特化一个方法并非易事。
这里尝试混入提供 class 标签的专门方法。
Specialized f
调用 specialized ct
,它在 trait 中被覆盖。
我不知道 ct
的伪参数对于使其专业化是必要的;也许 ClassTag[A]
结果类型不够。
$ scalam
Welcome to Scala 2.12.0-M3 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_60).
Type in expressions for evaluation. Or try :help.
scala> import reflect.ClassTag
import reflect.ClassTag
scala> class CT[@specialized(Int) A] {
| def ct(a: A): ClassTag[A] = ???
| def f: Array[A] = ct(null.asInstanceOf[A]).newArray(1)
| }
defined class CT
scala> trait CTS { def ct$mcI$sp(i: Int): ClassTag[Int] = reflect.classTag[Int] }
defined trait CTS
scala> (new CT[Int] with CTS).f
res0: Array[Int] = Array(0)
显示专门调用:
scala> :javap -c -
Compiled from "<console>"
[snip]
16: invokevirtual #32 // Method $line16/$read$$iw$$iw$$anon.f$mcI$sp:()[I
19: putfield #24 // Field res0:[I
当我有一个@specialized class 时,我会保留有关我的类型是什么基元的信息。有没有 fast 的方法来获得 ClassTag[T]
,例如创建数组?
这不会编译,因为没有可用的 ClassTag[T]
class Foo[@specialized T] {
def bar: Array[T] = new Array[T]
}
这可行,但我想避免传递 ClassTag
class Foo[@specialized T: ClassTag] {
def bar: Array[T] = new Array[T]
}
这有效,但速度很慢:
class Foo[@specialized T] {
def bar: Array[T] = new Array[T]
implicit def classTag: ClassTag[T] = {
val name = getClass.getName
if(name.endsWith("$I$sp") ClassTag.Int
else if(name.endsWith("$L$sp") ClassTag.Long
else ??? // you get the idea
}
}
专业化发生在打字机上 ClassTags 的具体化之后,所以这是谷仓门的问题。
另一个问题是特化会创建双重定义,因此以明显的方式手动特化一个方法并非易事。
这里尝试混入提供 class 标签的专门方法。
Specialized f
调用 specialized ct
,它在 trait 中被覆盖。
我不知道 ct
的伪参数对于使其专业化是必要的;也许 ClassTag[A]
结果类型不够。
$ scalam
Welcome to Scala 2.12.0-M3 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_60).
Type in expressions for evaluation. Or try :help.
scala> import reflect.ClassTag
import reflect.ClassTag
scala> class CT[@specialized(Int) A] {
| def ct(a: A): ClassTag[A] = ???
| def f: Array[A] = ct(null.asInstanceOf[A]).newArray(1)
| }
defined class CT
scala> trait CTS { def ct$mcI$sp(i: Int): ClassTag[Int] = reflect.classTag[Int] }
defined trait CTS
scala> (new CT[Int] with CTS).f
res0: Array[Int] = Array(0)
显示专门调用:
scala> :javap -c -
Compiled from "<console>"
[snip]
16: invokevirtual #32 // Method $line16/$read$$iw$$iw$$anon.f$mcI$sp:()[I
19: putfield #24 // Field res0:[I