Class Scala中具有行为的Case类

Class Scala中具有行为的Case类,class,scala,case,Class,Scala,Case,我有一个Scala case类,它有一些val作为参数。我有几个方法可以利用这个case类。假设我的案例类定义如下: case class CaseA(a: Int, b: List[CaseB]) case class CaseB(a: Int, b: text, c: Boolean) CaseA和CaseB都表示我的案例类的域模型。但当我在应用程序中使用它们时,我想根据CaseB的布尔字段向CaseA添加一些行为。例如,假设在CaseA中,val b有4个CaseB对象。我想添加一个通过

我有一个Scala case类,它有一些val作为参数。我有几个方法可以利用这个case类。假设我的案例类定义如下:

case class CaseA(a: Int, b: List[CaseB])
case class CaseB(a: Int, b: text, c: Boolean)
CaseA和CaseB都表示我的案例类的域模型。但当我在应用程序中使用它们时,我想根据CaseB的布尔字段向CaseA添加一些行为。例如,假设在CaseA中,val b有4个CaseB对象。我想添加一个通过b运行的行为,并告诉我CaseB中的任何一个元素的val c是否设置为true

我确实提出了以下实施案例A:

case class CaseA(a: Int, b: List[CaseB], c: Boolean)
但这种方法的问题是,当我从数据库加载CaseA对象时,我不需要val c,因为val c是计算出来的,而不是CaseA对象的一部分。我进一步修改了我的案例,如下所示:

case class CaseA(a: Int, b: List[CaseB], c: Option[Boolean])

我可以看出它已经变得难看了。如何将行为添加到案例类中,使val c不必是CaseA对象的一部分,而是每次在运行时都进行计算?

我不明白您对数据库做了什么。忽略这一点,我将执行以下操作:

case class CaseA(a: Int, b: List[CaseB]){
  val c = b.exists(_.c)
}
case class CaseB(a:Int,b:String,c:Boolean)
case class CaseA(a:Int,b:List[CaseB])
trait CanCheck extends CaseA{
    lazy val c = b exists (_.c)
}

val ca = new CaseA(42, List( 
    CaseB(1,"hello",false),
    CaseB(2,",",false),
    CaseB(3,"world",true))
    ) with CanCheck

println(ca.c)

如果不需要所有元素都使用c,我会使用一个惰性值

case class CaseB(a:Int,b:String,c:Boolean)
case class CaseA(a:Int,b:List[CaseB]){
    lazy val c = b exists (_.c)
}

val ca = CaseA(42, List( 
    CaseB(1,"hello",false),
    CaseB(2,",",false),
    CaseB(3,"world",true))
    )

println(ca.c)
要回答您的一些评论问题,如果您想使用mixin特性,可以执行以下操作:

case class CaseA(a: Int, b: List[CaseB]){
  val c = b.exists(_.c)
}
case class CaseB(a:Int,b:String,c:Boolean)
case class CaseA(a:Int,b:List[CaseB])
trait CanCheck extends CaseA{
    lazy val c = b exists (_.c)
}

val ca = new CaseA(42, List( 
    CaseB(1,"hello",false),
    CaseB(2,",",false),
    CaseB(3,"world",true))
    ) with CanCheck

println(ca.c)
请注意,您需要使用
new
关键字以两种方式执行此操作:

1) 将c定义为val,或者更好地定义为def:

case class CaseA(a: Int, b: List[CaseB]){
  val c = b.exists(_.c)
}
2) 使用隐式包装器:

case class CaseA(a: Int, b: List[CaseB])
implicit class CaseAC(underlying: CaseA) {
  val c = underlying.b.exists(_.c)
}
val x = CaseA(3, Nil)
// x: CaseA = CaseA(3,List())

x.c
// Boolean = false

如果不需要存储c,可以使用隐式值类,这些类甚至更薄

如何将行为b.exisis(u.c)从我的case类中分离出来?您可以使用函数def oneIsTrue(ca:CaseA)=ca.b.exists(u.c)轻松实现这一点,你应该想想这个功能实际上属于哪里。我在考虑更多关于使用一个特性的问题,这个特性有一个行为,我可以在我的案例类中混合使用它!如果需要重新计算,只需将“lazy val”替换为“def”。但用户代码将保持完全相同:)