作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
"xxx", "title"-> "yyy"),有没有办法将其一般转换为案例类图像(url:字符串,标题:字符串)? 我可以写一个助-6ren">
如果我有一个 Map[String,String]("url"-> "xxx", "title"-> "yyy")
,有没有办法将其一般转换为案例类图像(url:字符串,标题:字符串)
?
我可以写一个助手:
object Image{
def fromMap(params:Map[String,String]) = Image(url=params("url"), title=params("title"))
}
但是有没有一种方法可以为任何案例类的映射一般编写一次?
最佳答案
首先,如果您只是想缩短代码,可以采取一些安全的替代方法。伴生对象可以被视为一个函数,因此您可以使用如下所示的内容:
def build2[A,B,C](m: Map[A,B], f: (B,B) => C)(k1: A, k2: A): Option[C] = for {
v1 <- m.get(k1)
v2 <- m.get(k2)
} yield f(v1, v2)
build2(m, Image)("url", "title")
这将返回一个包含结果的选项。或者,您可以使用 Scalaz 中的 ApplicativeBuilder,其内部功能几乎相同,但语法更好:
import scalaz._, Scalaz._
(m.get("url") |@| m.get("title"))(Image)
如果您确实需要通过反射来做到这一点,那么最简单的方法是使用 Paranamer(就像 Lift-Framework 那样)。 Paranamer 可以通过检查字节码来恢复参数名称,因此会影响性能,并且由于类加载器问题(例如 REPL),它无法在所有环境中工作。如果您将自己限制为仅具有 String
构造函数参数的类,那么您可以这样做:
val pn = new CachingParanamer(new BytecodeReadingParanamer)
def fill[T](m: Map[String,String])(implicit mf: ClassManifest[T]) = for {
ctor <- mf.erasure.getDeclaredConstructors.filter(m => m.getParameterTypes.forall(classOf[String]==)).headOption
parameters = pn.lookupParameterNames(ctor)
} yield ctor.newInstance(parameters.map(m): _*).asInstanceOf[T]
val img = fill[Image](m)
(请注意,此示例可以选择默认构造函数,因为它不会检查您想要执行的参数计数)
关于class - 如何将 Map 转换为 Scala 中的案例类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6181845/
我是一名优秀的程序员,十分优秀!