当我有一个@specialized类时,我保留有关我的类型是什么原始类型的信息。是否有获取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
  }
}

最佳答案

专门化发生的时间晚于在Typer上实现ClassTags的活动,因此存在仓库门的问题。

另一个问题是专门化将创建双重定义,因此以明显的方式手工专门化方法并不容易。

这是尝试混入提供类标签的专用方法的尝试。

专用f调用在特征中被覆盖的专用ct

我不知道要使ct专用arg变得专用。也许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$1.f$mcI$sp:()[I
      19: putfield      #24                 // Field res0:[I

09-05 19:40