Class Scala中具有行为的Case类
我有一个Scala case类,它有一些val作为参数。我有几个方法可以利用这个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对象。我想添加一个通过
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”。但用户代码将保持完全相同:)