从专业课程中获取ClassTag [英] Get ClassTag from within specialized class

查看:97
本文介绍了从专业课程中获取ClassTag的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我有一个@specialized类时,我保留有关我的类型是什么原始类型的信息.是否有快速方法来获取ClassTag[T],例如创建数组?

When I have a @specialized class, I retain the information about what primitive my type is. Is there a fast way to get a ClassTag[T], e.g. to create arrays?

由于没有ClassTag [T]可用,因此无法编译

This does not compile, because no ClassTag[T] is available

class Foo[@specialized T] {
  def bar: Array[T] = new Array[T]
}

这可行,但我想避免传递ClassTag

This works, but I want to avoid passing the 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上实现ClassTag的时间,因此存在仓库门的问题.

Specialization happens later than materialization of ClassTags at typer, so there's the matter of the barn door.

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

The other issue is that specialization will create double definitions, so it's not trivial to hand-specialize a method in the obvious way.

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

Here's an attempt to mix-in the specialized method that provides a class tag.

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

Specialized f calls specialized ct which is overridden in the trait.

我不知道要使ct的伪arg专门化是必需的;可能ClassTag[A]结果类型还不够.

I don't know that the dummy arg to ct is necessary to make it specialize; maybe the ClassTag[A] result type isn't enough.

$ 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

这篇关于从专业课程中获取ClassTag的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆