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

在Scala中对HashMap进行子类化,解决类型擦除问题

发布时间:2020-12-16 08:46:57 所属栏目:安全 来源:网络整理
导读:让我们说,出于某种原因,我想要一个包含所有类型对象的通用HashMap.我还想将任何难看的类似实例的类型检查推送到数据结构中.为此,像getAs [T:Any](key:String):Option [T]这样的方法会很好. class State extends HashMap[String,Any] { override def +[T :
让我们说,出于某种原因,我想要一个包含所有类型对象的通用HashMap.我还想将任何难看的类似实例的类型检查推送到数据结构中.为此,像getAs [T<:Any](key:String):Option [T]这样的方法会很好.

class State extends HashMap[String,Any] {

  override def +[T >: Any](elem: (String,T)): State = super.+(elem)
  override def -(key: String): State = super.-(key)

  def getAs[T](key: String): Option[T] = {
    super.get(key) match {
      case s: Some[T] => s
      case _ => None
    }
  }

}
object State extends HashMap[String,Any] {
  override def empty: State = super.empty
}

我还在包对象中定义了以下隐式转换:

implicit def fromHashMap(m: HashMap[String,Any]): State = m.asInstanceOf[State]

当我编译上面的代码时,我得到以下类型的擦除警告:

State.scala:10: warning: non variable type-argument T in type pattern Some[T] is
unchecked since it is eliminated by erasure
case s: Some[T] => s
        ^

这是不幸的,因为该语句的整个目的是检查类型!

在这种情况下,除了采用实验性Manifest功能之外,我还有其他选择吗?此外,有没有更好的基本方法来实现这一目标?

编辑:

我使用Manifest工作了. Stackoverflow上我在this article的帮助很大.但是,如果有人可以推荐更清洁的方式,我仍然很好奇.

双重编辑:

这是当前版本.清单解决了我的直接问题.但是,我做的一个重大改变是使State类成为Map的包装器.这样做,我失去了继承的优点(即现在我必须明确地公开每个map方法,我需要一个la keySet如下.

class State(
  map: HashMap[String,(Manifest[_],Any)] = 
    scala.collection.immutable.HashMap.empty[String,Any)]
) extends java.io.Serializable {

  def +[T <: Any](elem: (String,T))(implicit m: Manifest[T]): State =
    State(map.+((elem._1,(m,elem._2))))

  def -(key: String): State = State(map.-(key))

  def keySet = map.keySet

  def getAs[T](key: String)(implicit m : Manifest[T]): Option[T] = {
    map.get(key) match {
      case Some((om: Manifest[_],o: Any)) =>
        if (om <:< m) Some(o.asInstanceOf[T]) else None
      case _ => None
    }
  }

}

object State {
  def apply() = new State()
  def apply(map: HashMap[String,Any)]) = new State(map)
  def empty = State()
}

感谢所有到目前为止看过这个的人.

Scala 2.10更新:

使用ClassTag和朋友here on GitHub查看State的当前实现.一旦TypeCreators可序列化,我计划更新它以使用TypeTags.

解决方法

请注意,虽然

case s: Some[T]

不起作用,因为某些类型参数被删除,这是不同的:

case s @ Some(_: T)

在这种情况下,它不起作用,因为T本身就是一个类型参数.虽然这对你的情况没有影响(不,除了清单之外别无选择),请考虑以下事项:

case s: Some[Int]      // erased
case s @ Some(_: Int)  // not erased

(编辑:李大同)

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

    推荐文章
      热点阅读