【问题标题】:Scala How to write a get(name:String, type:Class) for mapScala如何为地图编写get(name:String,type:Class)
【发布时间】:2014-11-18 06:40:41
【问题描述】:

我希望能够有一个 [String,Any] 类型的地图实现,我可以在其中存储不同类的对象,然后我希望能够这样做

import app.User;
....
usr = map.getAs("user",User)// with usr being an object of Class/Object User. If user is not of that type it throws an exception.

用户之前在地图中的存储位置。

这可能吗?

我什至可以是一个独立的方法,例如

 usr = getAs(map,"user",User)

谢谢

【问题讨论】:

    标签: scala


    【解决方案1】:

    您可以使用ClassTag。我没有太多的经验,但类似的东西应该可以工作:

    def getAs[T: ClassTag](m: Map[String, Any], key: String): T = 
      m(key).asInstanceOf[T]
    

    用法:

    val map = Map[String, Any]("one" -> 1, "hello"-> "world")
    getAs[String](map, "hello")
    res1: String = world
    

    我让你处理异常,你可以简单地将asInstanceOf 包装在Try 中,或者任何你喜欢的策略。我还建议将返回类型更改为Option[T]

    【讨论】:

      【解决方案2】:

      感谢 vptheron。这绝对有效。 我接受了您的建议,并使用 Option[T] 并使用了匹配。

      def getAsOption[T: ClassTag](m: Map[String, Any], key: String): Option[T] =
      m.get(key) match {
          case x : Option[T] => x
          case _ => None
      }   
      

      我想要一种机制来在游戏框架中传递随机的东西,这对我来说似乎是一个很好的解决方案,尽管纯粹主义者不会喜欢它。

      【讨论】:

      • 在我的 REPL 中使用 getAsOption[Int](Map[String, Any]("1" -> "hello"), "1") 会产生 Option[Int] = Some(hello)。这当然是无稽之谈,当您对该选项使用操作时会抛出异常,例如get。在@vptheron 的回答中直接抛出异常。
      【解决方案3】:

      我认为使用TypeTag 会做得更好,除非您永远不会将值转换为泛型类型。

      import scala.reflect.runtime.universe._
      
      trait Typed[A] {
        val value: A
        implicit val ttag: TypeTag[A]
      }
      
      def cast[A, B: TypeTag](v: Typed[A]): Option[B] = {
        val tA = typeOf[A](v.ttag)
        val tB = typeOf[B]
        def vB = v.value.asInstanceOf[B]
        if (tA <:< tB) Some(vB) else None
      }
      
      def getTyped[A, B, C: TypeTag](map: Map[A, Typed[B]], key: A): Option[C] = {
        map get key flatMap cast[B, C]
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-05-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-05-28
        相关资源
        最近更新 更多