Scala 任何 => 原生格式



我有一个类型为Map[_, Any]的映射,我想以它们的原生格式提取值(不需要使用.asInstanceOf[_](。

像这样的。。。

val m: Map[String, Any] = Map("i" -> 1, "s" -> "test")
val i: Option[Int] = m.get("i")
val s: Option[String] = m.get("s")

显然,这是失败的。

我不喜欢这种方法,但我想我可以做这样的事情。。。但即使是这样,仍然作为CCD_ 3而不是CCD_ 4或CCD_。

trait MyType[A] {
def value: A
}
implicit class MyInt(i: Int) extends MyType[Int] { def value: Int = i }
implicit class MyString(s: String) extends MyType[String] { def value: String = s }
val m: Map[String, MyType[_]] = Map("i" -> 1, "s" -> "test")
val i: Option[Int] = m.get("i").map(_.value)
val s: Option[String] = m.get("s").map(_.value)

然后我想也许是Map的包装。。。

case class MyMap(m: Map[String, Any]) {
def get[A](k: String)(implicit ev: Option[Any] => Option[A]): Option[A] = m.get(k)
}

但这仍然是Any。我只是不知道如何转换Any=>出生地的

所以我的问题是。。。

  1. 为什么会失败
  2. 有什么更好的方法可以将值以其原生格式输出?最简单和/或没有外部依赖关系将是理想的。。。但老实说,我对任何事情都持开放态度(不过需要注意的是,我现在仍在使用scala2.11(

谢谢!

由于注释中已经解释过的原因,您无法猜测运行时类型-这些信息不存在,一旦是Any,所有类型信息都会丢失,对此您无能为力。

因此,您必须自己提供期望的类型。.as[T]辅助方法怎么样?

// This code is specifically for 2.11, please don't use it for more recent versions,
// see link below.
val m: Map[String, Any] = Map("i" -> 1, "s" -> "test")
import scala.reflect.{ ClassTag, classTag }
implicit class As(a: Any) {
def as[T](implicit ct: ClassTag[T]): Option[T] = ct.unapply(a)
}
println(m("i").as[Int].map(_ + 41).get)
println(m("s").as[String].map("This is a " + _).get)

这将打印

42
This is a test

简要说明:

  • CCD_ 10包装器";皮条客;所有对象,并将.as方法附加到所有对象
  • unapplyOption中进行检查、铸造和包装

它不适用于List[Int]List[String]等泛型类型,因为这些信息在运行时根本不可用。

编辑:感谢@MarioGalic大大简化了解决方案。

最新更新