我正在尝试将类型标记转换为维护/保留通常删除的类型参数的 java 类。有相当多的库受益于这些转换(例如 Jackson 和 Guice)。我目前正在尝试将基于 Manifest
的代码迁移到 TypeTag
,因为 Manifest
不足以满足某些极端情况。
与其他数据类型相比,JVM 将数组视为特殊的。 classOf[Int]
和 classOf[Array[Int]]
之间的区别在于,方法 Class.isArray()
将返回 true后者。
Manifest 的实现很简单。 Manifest.erasure
是一个 Class
实例,其中 isArray()
已经有效/true。
TypeTag
的实现比较棘手。没有快速简便的删除
方法。事实上,“类似”的 TypeTag 变体,RuntimeMirror.runtimeClass
,不喜欢代表我们处理创建任何基于数组的类。阅读文档:
Note: If the Scala symbol is ArrayClass, a ClassNotFound exception is thrown because there is no unique Java class corresponding to a Scala generic array
为了解决这个问题,我尝试检测它是否是一个数组。如果它是一个数组,那么我手动创建类对象。但是,当 Array 具有未知类型参数时,我遇到了额外的边缘情况。
首先让我向您展示一个不是 HighKinded 类型的示例。
import scala.reflect.runtime.universe._
class A[T]
val innerType = typeOf[A[Array[_]]].asInstanceOf[TypeRefApi].args.head
innerType <:< typeOf[Array[_]] // Returns true.
到目前为止一切顺利。
class B[T[_]]
val innerType = typeOf[B[Array]].asInstanceOf[TypeRefApi].args.head
innerType <:< typeOf[Array[_]] // Returns false.
我无法创建 typeOf[Array],因为它提示缺少参数。如何检测 B 的类型参数为 Array?
此外,在这种情况下类实例会是什么样子?它是一个数组[对象]吗?
最佳答案
再次分解:
scala> innerType match { case TypeRef(pre, sym, args) => sym == definitions.ArrayClass }
res13: Boolean = true
这可能会让你半途而废。
关于scala - 如何检查 Scala HighKinded TypeTag 是否为数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28092164/