scala - 如何检查 Scala HighKinded TypeTag 是否为数组?

标签 scala reflection

我正在尝试将类型标记转换为维护/保留通常删除的类型参数的 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/

相关文章:

data-binding - 关于 Scala 字段和属性更改事件

arrays - Array 与 ArraySeq 比较

java - 在Java中,可以将一行代码作为方法参数吗?

reflection - 去(反射): How to Instantiate an arbitrary type and set a known embedded field

Scala:使用模式匹配检测 5 张扑克牌中的顺牌

scala - 在 akka-http Scala 中将泛型类型注册到 spray-json-support 的正确方法是什么?

java - 我如何仅根据方法名称知道方法返回类型?

reflection - GO 语言 : anonymous structs & Reflection combination

c# - HasThis 和 ExplicitThis 调用约定

scala - 为什么在这种情况下 classOf[...] 会显示 'not found: type foo' ?