Scala实施

时间:2017-11-06 14:35:33

标签: scala

我有一个案例类:

case class EvaluateAddress(addressFormat: String,
                           screeningAddressType: String,
                           value: Option[String])

这个工作正常,直到我有一个新的用例,其中“value”参数可以是类Object而不是String。

我处理此用例的初始实现:

case class EvaluateAddress(addressFormat: String,
                           screeningAddressType: String,
                           addressId: Option[String],
                           addressValue: Option[MailingAddress]) {


  def this(addressFormat: String, screeningAddressType: String, addressId: String) = {
    this(addressFormat, screeningAddressType, Option(addressId), None)
  }

  def this(addressFormat: String, screeningAddressType: String, address: MailingAddress) = {
    this(addressFormat, screeningAddressType, None, Option(address))
  }
}

但由于某些问题,我在任何构造函数中都不能有四个参数。

有没有办法可以创建一个包含三个参数的类:** addressFormat,screeningAddressType,value **并处理这两个用例?

2 个答案:

答案 0 :(得分:1)

您的代码运行正常,要使用其他构造函数,您只需使用new关键字:

case class MailingAddress(i: Int)

case class EvaluateAddress(addressFormat: String, screeningAddressType: String, addressId: Option[String], addressValue: Option[MailingAddress]) {

  def this(addressFormat: String, screeningAddressType: String, addressId: String) = {
    this(addressFormat, screeningAddressType, Option(addressId), None)
  }

  def this(addressFormat: String, screeningAddressType: String, address: MailingAddress) = {
    this(addressFormat, screeningAddressType, None, Option(address))
  }
}

val e1 = EvaluateAddress("a", "b", None, None)
val e2 = new EvaluateAddress("a", "b", "c")
val e3 = new EvaluateAddress("a", "b", MailingAddress(0))

答案 1 :(得分:0)

您可以创建辅助ADT来包装不同类型的值。在EvaluateAddress内,您可以查看match提供的替代方案:

case class EvaluateAddress(addressFormat: String,
  screeningAddressType: String,
  value: Option[EvaluateAddress.Value]
) {
  import EvaluateAddress._

  def doEvaluation() = value match {
    case Some(Value.AsId(id)) => 
    case Some(Value.AsAddress(mailingAddress)) => 
    case None => 
  }
}

object EvaluateAddress {
  sealed trait Value
  object Value {
    case class AsId(id: String) extends Value
    case class AsAddress(address: MailingAddress) extends Value
  }
}

然后可以定义一些隐式转换,以自动将StringMailingAddress es转换为Value s:

object EvaluateAddress {
  sealed trait Value
  object Value {
    case class AsId(id: String) extends Value
    case class AsAddress(address: MailingAddress) extends Value

    implicit def idAsValue(id: String): Value = AsId(id)
    implicit def addressAsValue(address: MailingAddress): Value = AsAddress(address)
  }

  def withRawValue[T](addressFormat: String,
    screeningAddressType: String,
    rawValue: Option[T])(implicit asValue: T => Value): EvaluateAddress = 
  {
    EvaluateAddress(addressFormat, screeningAddressType, rawValue.map(asValue))
  }
} 

使用这些隐式转换的一些示例:

scala> EvaluateAddress("a", "b", Some("c"))
res1: EvaluateAddress = EvaluateAddress(a,b,Some(AsId(c)))

scala> EvaluateAddress("a", "b", Some(MailingAddress("d")))
res2: EvaluateAddress = EvaluateAddress(a,b,Some(AsAddress(MailingAddress(d))))

scala> val id: Option[String] = Some("id")
id: Option[String] = Some(id)

scala> EvaluateAddress.withRawValue("a", "b", id)
res3: EvaluateAddress = EvaluateAddress(a,b,Some(AsId(id)))