处理重复案例的惯用方法 类
Idiomatic way to deal with Repetitive Case Classes
我正在学习案例 classes。据我了解,案例 classes 无法通过其他案例 classes 进行扩展。处理以下问题的惯用方法是什么:
我有两个案例 classes,A 和 B。它们是相同的,并提供给另一个案例 Class C。现在当我想定义一个“+”函数时,问题就出现了。这可以在下面看到:
object Example extends App {
// repetitive case classes A and B - Can they be abstracted to one case class?
case class A(a: Int, b: String) {
def f1(): Unit = println(a, b)
}
case class B(a: Int, b: String) {
def f1(): Unit = println(a, b)
}
case class C(a: A, b: B) {
def serialize() = Map("a" -> a, "b" -> b)
def +(new_a: A): C = C(new_a, b)
def +(new_b: B): C = C(a, new_b)
}
}
以上编译通过,但是很重复。如果我删除 case class B,只使用 case class A,我可以尝试做这样的事情:
// if I use the same type for both A and B, I cannot use + individually anymore
case class C_alt(a: A, b: A) {
def serialize() = Map("a" -> a, "b" -> b)
def +(new_a: A): C_alt = C_alt(new_a, b)
def +(new_b: A): C_alt = C_alt(a, new_b)
}
但是,我现在不能同时拥有 A 和 B 的“+”函数,因为类型相同并且重载失败。
解决此代码重复问题的惯用 Scala 方法是什么?理想情况下,我希望有一个常见的案例 class 实现这些方法,并且 A 和 B 都扩展它。但是由于 case class 不允许由另一个 case class 扩展,我应该使用正常的 class 吗?
首先可以按照大家的建议使用普通的class
。您可以使用 copy
(为案例 类 提供)而不是您的 +
方法。
但是,如果您想获得免费的 case class
函数并且您有多种常见行为,那么您可以使用 trait
来抽象出您的类型的行为。
trait TDemo {
def i: Int
def s: String
def f1(): Unit = println(i, s)
def f2(): Int = i + 10
def f3(): String = s + " LOL"
def toString: String
}
case class Demo1(a: Int, b: String) extends TDemo
case class Demo2(a: Int, b: String) extends TDemo
trait TDemoWrapper[A <: TDemo, B <: TDemo] {
def a: A
def b: B
def serialize() = Map("a" -> a, "b" -> b)
def f1(): Unit = println(s"a :: $a, b :: $b")
}
case class DemoWrapper1(a: Demo1, b: Demo2) extends TDemoWrapper[Demo1, Demo2]
case class DemoWrapper2(a: Demo1, b: Demo1) extends TDemoWrapper[Demo1, Demo1]
我正在学习案例 classes。据我了解,案例 classes 无法通过其他案例 classes 进行扩展。处理以下问题的惯用方法是什么:
我有两个案例 classes,A 和 B。它们是相同的,并提供给另一个案例 Class C。现在当我想定义一个“+”函数时,问题就出现了。这可以在下面看到:
object Example extends App {
// repetitive case classes A and B - Can they be abstracted to one case class?
case class A(a: Int, b: String) {
def f1(): Unit = println(a, b)
}
case class B(a: Int, b: String) {
def f1(): Unit = println(a, b)
}
case class C(a: A, b: B) {
def serialize() = Map("a" -> a, "b" -> b)
def +(new_a: A): C = C(new_a, b)
def +(new_b: B): C = C(a, new_b)
}
}
以上编译通过,但是很重复。如果我删除 case class B,只使用 case class A,我可以尝试做这样的事情:
// if I use the same type for both A and B, I cannot use + individually anymore
case class C_alt(a: A, b: A) {
def serialize() = Map("a" -> a, "b" -> b)
def +(new_a: A): C_alt = C_alt(new_a, b)
def +(new_b: A): C_alt = C_alt(a, new_b)
}
但是,我现在不能同时拥有 A 和 B 的“+”函数,因为类型相同并且重载失败。
解决此代码重复问题的惯用 Scala 方法是什么?理想情况下,我希望有一个常见的案例 class 实现这些方法,并且 A 和 B 都扩展它。但是由于 case class 不允许由另一个 case class 扩展,我应该使用正常的 class 吗?
首先可以按照大家的建议使用普通的class
。您可以使用 copy
(为案例 类 提供)而不是您的 +
方法。
但是,如果您想获得免费的 case class
函数并且您有多种常见行为,那么您可以使用 trait
来抽象出您的类型的行为。
trait TDemo {
def i: Int
def s: String
def f1(): Unit = println(i, s)
def f2(): Int = i + 10
def f3(): String = s + " LOL"
def toString: String
}
case class Demo1(a: Int, b: String) extends TDemo
case class Demo2(a: Int, b: String) extends TDemo
trait TDemoWrapper[A <: TDemo, B <: TDemo] {
def a: A
def b: B
def serialize() = Map("a" -> a, "b" -> b)
def f1(): Unit = println(s"a :: $a, b :: $b")
}
case class DemoWrapper1(a: Demo1, b: Demo2) extends TDemoWrapper[Demo1, Demo2]
case class DemoWrapper2(a: Demo1, b: Demo1) extends TDemoWrapper[Demo1, Demo1]