我怎么能scala-ify这个块:

时间:2014-03-07 01:02:14

标签: scala

斯卡拉新手在这里...... 我怎样才能对这个块进行scalized:

if(sess != null) {
  sess.any = params.get("any").getOrElse("")
  sess.name = params.get("name").getOrElse("")
  sess.entity = params.get("entity").getOrElse("")
  sess.tin = params.get("tin").getOrElse("")
  sess.tintype = params.get("tintype").getOrElse("")
  sess.bdate = params.get("bdate").getOrElse("")
  sess.addr = params.get("addr").getOrElse("")
  sess.city = params.get("city").getOrElse("")
  sess.state = params.get("state").getOrElse("")
  sess.zip = params.get("zip").getOrElse("")
}

sess只是案例类的一个实例。

3 个答案:

答案 0 :(得分:1)

您通常不会使sess变得可变,但这里最简单的解决方案是拔出可移动的公共代码。您通常无法按名称查找和设置字段,因此sess.x =部分必须保留,并且案例类没有与其字段名称匹配的字符串,因此"x"必须保留。离开

if (sess != null) {
  def get(s: String) = params.get(s).getOrElse("")
  sess.any = get("any")
  /* ... */
  sess.zip = get("zip")
}

仍然有很多样板,但可能比反思更好,并且肯定是一种改进。

答案 1 :(得分:0)

在这种情况下,您可能需要考虑将键值映射包装到一个简单的类中。

通过这种方式,您可以编写自定义方法来添加/删除/检查类似于访问案例类的元素。

如果您希望键的类型安全,则地图的键可以是扩展常见特征的对象,如:

trait MyKey
object AnyKey extends MyKey
object NameKey extends MyKey

MyKey也可以有一个字符串field,可以在填充地图时调用params.get()方法时使用。

然后,您可以将所有密钥放入List[MyKey]并在列表中执行foreach以填充地图。

如果您需要在此包装类上进行模式匹配,则可以使用extractors

答案 2 :(得分:0)

使用Shapeless 2.0.0的解决方案。首先假设缩短版sess

case class sess(val any: String, val name: String, val entity: String)

及其成员名称列表(此问题中的参数),

val args = List("any", "name", "entity")

或者例如

val args = "any,name,entity".split(",").toList

定义用于获取可能参数值的get方法,如已建议的那样,

implicit class parameterGetter( val parameters: Map[String,String]) extends AnyVal {
  def get(s: String) = parameters.get(s).getOrElse("")
}

假设问题中的paramsMap[String,String]

然后为每个参数获取一个值

val argsVals = args.map { a => params.get(a).get }

和结果,

import shapeless._
import HList._
import syntax.std.traversable._

// Especially useful if case class includes different types
val argsH = argsVals.toHList[String::String::String::HNil]
val argsTupled = argsH.get.tupled 

对于案例类,例如

case class sees2(val city: String, val x: Int, val y: Int)

toHList中的输入将改为String::Int::Int::HNil

最后,创建一个sess

的实例
val mySess = sess.tupled(argsTupled)

通过从mySess

获取值来测试此项
mySess.any
mySess.name
mySess.entity