scala – 从Any到AnyRef的通用/通用拳击
是否可以动态强制在
scala中运行时装箱?我想要一个功能:
def box(value :Any) :AnyRef 要么 def box[T](value :T) :AnyRef 我有一个泛型类,可以使用AnyVals进行参数化,但需要将它们传递给接受对象集合的旧Java方法.当然,我可以自己使用模式匹配来实现它,但是它必须一次又一次地做它有点烦人,并且它对用户值类不起作用. 编辑 答案变得简单,令人惊讶.现在,我可以通过反思来做到吗?假设 class Box[T :TypeTag](private var value :T) { def get :T = value def set(o :Any) { ... } } 我想做一个安全集,检查运行时是否o是T的子类,如下所示: runtimeMirror(getClass.getClassLoader).classSymbol(o.getClass).toType <:< typeOf[T] 不幸的是,Box [Long]的typeOf [T]将是一个原语,并且以下检查将在java.lang.Long上失败,例如,Seq [Long]的元素的运行时类型.最后,当使用泛型与AnyVals时,编译器有时会将它们设置为使得运行时类检查不可预测. 解决方法
只需使用asInstanceOf转换为AnyRef,Scala会将其转换为AnyRef:
scala> val x = 13 x: Int = 13 scala> val xBoxed = x.asInstanceOf[AnyRef] xBoxed: AnyRef = 13 scala> xBoxed.getClass() res0: Class[_ <: AnyRef] = class java.lang.Integer 对于值类,这将把它封装在值类的实例中,而不是Java类中.您可以使用通用特征来从您的值类中获取Java盒装版本,而无需使用反射.例如: trait ValueClass[T] extends Any { def value: T def javaBoxed: AnyRef = value.asInstanceOf[AnyRef] } case class MyInt(value: Int) extends AnyVal with ValueClass[Int] case class MyReal(asDouble: Double) extends AnyVal with ValueClass[Double] { def value = asDouble } 但是,这需要您将特征混合到所有值类中.对于扩展 def javaBox(x: Product): AnyRef = { if (x.productArity == 1) x.productElement(0).asInstanceOf[AnyRef] else x.asInstanceOf[AnyRef] // or throw an exception if you prefer } 不幸的是,它看起来对我来说,这两种方法(混合式特征和产品)事业斯卡拉做它的拳击,这意味着呼吁未装箱的值时,该值从拆箱进入→斯卡拉装箱→取消装箱→Java的盒装,而不是直Java盒装值. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |