加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

Scala asInstanceOf与参数化类型

发布时间:2020-12-16 09:42:32 所属栏目:安全 来源:网络整理
导读:我想写一个类型A的函数,其中A可以是例如列表[Int]或更复杂的参数化类型,如Map [Int,List [Int]]。 def castToType[A](x: Any): A = { // throws if A is not the right type x.asInstanceOf[A]} 现在,由于类型擦除(我相信),即使类型不正确,代码也可以
我想写一个类型A的函数,其中A可以是例如列表[Int]或更复杂的参数化类型,如Map [Int,List [Int]]。

def castToType[A](x: Any): A = {
  // throws if A is not the right type
  x.asInstanceOf[A]
}

现在,由于类型擦除(我相信),即使类型不正确,代码也可以快速运行。该错误只表示访问,与ClassCastException。

val x = List(1,2,3)
val y = castToType[List[String]](x)
y(0) --> throws java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String

有没有办法使用清单来使这项工作正常运作?谢谢!

解决方法

不幸的是,这在asInstanceOf的固有局限性。我真的很惊讶,在 details年可以看到它的提及:

Note that the success of a cast at runtime is modulo Scala’s erasure semantics. Therefore the expression 1.asInstanceOf[String] will throw a ClassCastException at runtime,while the expression List(1).asInstanceOf[List[String]] will not. In the latter example,because the type argument is erased as part of compilation it is not possible to check whether the contents of the list are of the requested type.

如果你主要关心错误的转换失败,这可能是从DB / memcached接口获取内容时的主要问题,我正在玩耍强制对可移动对象的头像:

def failFastCast[A: Manifest,T[A] <: Traversable[A]](as: T[A],any: Any) = { 
  val res = any.asInstanceOf[T[A]]
  if (res.isEmpty) res 
  else { 
    manifest[A].newArray(1).update(0,res.head) // force exception on wrong type
    res
  }
}

在一个简单的例子上它的作品:

scala> val x = List(1,3): Any
x: Any = List(1,3)

scala> failFastCast(List[String](),x)
java.lang.ArrayStoreException: java.lang.Integer
[...]

scala> failFastCast(List[Int](),x)
res22: List[Int] = List(1,3)

但不是更复杂的一个:

val x = Map(1 -> ("s" -> 1L)): Any
failFastCast(Map[Int,(String,String)](),x) // no throw

我想知道是否有一种方法可以递归深入到A中以保持投射,直到没有更多的类型参数…

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读