scala – 如何使用新的反射API来判断数组的组件类型是否符合类型
发布时间:2020-12-16 09:49:11 所属栏目:安全 来源:网络整理
导读:如果我有方法…… def arrayConformsTo[A](as: Array[_]) = ??? …我可以根据需要在A中添加Context Bounds.我希望此方法查看Array的组件类型,如果这是A的子类型,则返回true.例如: arrayConformsTo[Int](Array(1,2,3)) //returns truearrayConformsTo[String
如果我有方法……
def arrayConformsTo[A](as: Array[_]) = ??? …我可以根据需要在A中添加Context Bounds.我希望此方法查看Array的组件类型,如果这是A的子类型,则返回true.例如: arrayConformsTo[Int](Array(1,2,3)) //returns true arrayConformsTo[String](Array(1,3)) //returns false 在2.10之前,这将完成如下: def arrayConformsTo[A: Manifest](as: Array[_]) = ClassManifest.fromClass(as.getClass.getComponentType) <:< manifest[A] 但是,这现在编译了弃用警告 <console>:8: warning: method <:< in trait ClassManifestDeprecatedApis is deprecated: Use scala.reflect.runtime.universe.TypeTag for subtype checking instead ClassManifest.fromClass(as.getClass.getComponentType) <:< manifest[A] ^ <console>:8: warning: value ClassManifest in object Predef is deprecated: Use scala.reflect.ClassTag instead ClassManifest.fromClass(as.getClass.getComponentType) <:< manifest[A] 我对此的第一个猜测如下: scala> def arrayConformsTo[A: reflect.ClassTag](as: Array[_]) = | reflect.ClassTag(as.getClass.getComponentType) <:< implicitly[reflect.ClassTag[A]] 但这也给出了弃用警告 <console>:8: warning: method <:< in trait ClassManifestDeprecatedApis is deprecated: Use scala.reflect.runtime.universe.TypeTag for subtype checking instead reflect.ClassTag(as.getClass.getComponentType) <:< implicitly[reflect.ClassTag[A]] ^ 它告诉我使用TypeTag.但是怎么样?这甚至是一个有效的问题反思? 附录:虽然它对AnyVal不起作用,但它似乎对我需要的东西合理地工作: scala> def arrayConformsTo[A: reflect.ClassTag](as: Array[_]) = | implicitly[reflect.ClassTag[A]].runtimeClass isAssignableFrom as.getClass.getComponentType 解决方法
scala反射api肯定是一个迷宫,但至少它是全面的:
import scala.reflect.runtime.{universe => ru} def arrayConformsTo[A: ru.TypeTag](as: Array[_]) = { val mirror = ru.runtimeMirror( getClass.getClassLoader ) val classSym = mirror.classSymbol( as.getClass.getComponentType ) classSym.toType <:< implicitly[ru.TypeTag[A]].tpe } REPL测试: scala> arrayConformsTo[Float]( Array[Float]() ) res9: Boolean = true scala> arrayConformsTo[Int]( Array[Float]() ) res10: Boolean = false scala> arrayConformsTo[AnyVal]( Array[Float]() ) res11: Boolean = true scala> arrayConformsTo[AnyVal]( Array[Float]() ) res12: Boolean = true scala> arrayConformsTo[Any]( Array[Float]() ) res13: Boolean = true scala> arrayConformsTo[Any]( Array[Float]() ) res14: Boolean = true scala> arrayConformsTo[AnyRef]( Array[Float]() ) res15: Boolean = false scala> arrayConformsTo[AnyRef]( Array[Float]() ) res16: Boolean = false (由于完整性原因,由OP编辑) 另一个解决方案(不需要scala-reflect.jar),虽然不能保留Float<:< AnyVal是true属性是使用ClassTag作为提取器: scala> def arrayConformsTo[A](as: Array[_])(implicit arrayOfA: ClassTag[Array[A]]) | = as match { | case arrayOfA(_) => true | case _ => false | } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |