如何创建允许键和值的多种类型的Map类型?

时间:2010-06-05 05:10:12

标签: scala manifest

我想创建一个Map类型,因此可以使用以下内容:

VariantMap(1) = "Test"
VariantMap("a") = 42

VariantMap("a")的类型为Option[Int]。这是我到目前为止的代码,结果是Option[Nothing]

object VariantMap {
  import scala.reflect.Manifest

  private var _map= Map.empty[Any,(Manifest[_], Any)] 

  def update[T](name: Any, item: T)(implicit m: Manifest[T]) {
    _map = _map(name) = (m, item)
  }

  def apply[T](key:Any)(implicit m : Manifest[T]) = {
    val o = _map.get(key)

    o match {
      case Some((om: Manifest[_], s : Any)) => Some[T](s.asInstanceOf[T])
      case _ => None
    }
  }
}

我是斯卡拉的新手,所以如果我遗漏了一些明显的东西,我会道歉。

1 个答案:

答案 0 :(得分:2)

我不确定是否可以直接做你想做的事。 apply方法采用类型参数[T],但如果不指定,则编译器不知道T的确切类型。在这种情况下,它推断Nothing,任何其他类型的子类型。

使用您的代码,提供类型参数会得到以下结果:


scala> VariantMap[Int]("a")
res0: Option[Int] = Some(1)

scala> VariantMap[String]("a")
res1: Option[String] = Some(1)

所以现在,任何类型都可以,也不完美。 您可以使用以下变体稍微改进它:


object VariantMap {
   import scala.reflect.Manifest

   private var _map= Map.empty[Any,(Manifest[_], Any)] 

   def update[T](name: Any, item: T)(implicit m: Manifest[T]) {
      _map = _map(name) = (m, item)
   }

   def apply[T](key:Any)(implicit m : Manifest[T]): Option[T] = {
     val o = _map.get(key)      
     o match {
       case Some((om: Manifest[_], s : Any)) => if (om  None
     }
  }
}

scala> VariantMap("a")
res0: Option[Nothing] = None

scala> VariantMap[Int]("a")
res1: Option[Int] = Some(1)

scala> VariantMap[String]("a")
res2: Option[String] = None

这可能也不是你想要的(这只是一个类型安全的地图),但我现在还没有真正看到更好的解决方案。