将不同类型的参数传递给 case class 的可能方法

Possible ways to pass argument of different type to case class

我想将不同类型的元素归为一类。

下面是一个例子

trait Element

case class ElementString(key:String,value:String) extends Element
case class ElementDouble(key:String,value:Double) extends Element
case class ElementInt(key:String,value:Int) extends Element

Grp(ElementString("2","abc"),ElementDouble("3",100.20),ElementInt("4",10))

已更新

我也想在群里创建群

您可以通过添加一个函数来使用准构建器模式:

def withElement(elem: Element) = copy(group = group :+ elem)

假设组是一个列表。请注意,这确实会在您每次调用 withElement 时创建案例 class 的新副本。代码将如下所示:

Grp().withElement(...).withElement(...)

如果性能很重要,您可以创建一个真正的构建器模式。

像这样的 DSL 在 Scala 中很常见,因为它是类型安全的,而且使用起来也非常简洁:

trait Value

object Value {
  case class StringValue(value: String) extends Value
  case class DoubleValue(value: Double) extends Value
  case class IntValue(value: Int) extends Value
}

case class Element(key: String, value: Value)
object Element {
  implicit def fromStringPair (a: (String,String)) = Element(a._1, Value.StringValue(a._2))
  implicit def fromDoublePair (a: (String,Double)) = Element(a._1, Value.DoubleValue(a._2))
  implicit def fromIntPair (a: (String,Int)) = Element(a._1, Value.IntValue(a._2))
}

case class Grp (elements: Element*)

Grp(
  "2" -> "abc",
  "3" -> 100.20,
  "4" -> 10
)

//: Grp = Grp(WrappedArray(Element(2,StringValue(abc)), Element(3,DoubleValue(100.2)), Element(4,IntValue(10))))

备选方案,无可变参数:

trait Value

// define these in different files if you want
case class Student(value: String) extends Value
case class Employee(value: Double) extends Value
case class Department(value: Int) extends Value

case class Element(key: String, value: Value)

case class Grp (elements: List[Element] = Nil) extends Value {
  def add (key: String, value: Value): Grp = Grp(this.elements ++ List(Element(key, value)))
}

Grp()
  .add("2", Student("abc"))
  .add("3", Employee(100.20))
  .add("4", Department(10))
  .add("5", Grp().add("2", Student("xyz"))) // nested group