我的模型看起来像这样:
abstract class A(id:String, val time:Int) extends Ordered[A]{
override def compare(that:TrackingEvent) = this.time.compare(that.time)
}
case class B(id:String, override val time: Int, x:Int, y:int) extends A(id,time) {
//some methods
}
// more Case Classes who inherit from A
我从mongodb获取一些数据并将它们存储在一些case-classes中(每个类继承自A)
我现在所做的是:
val header = getHeader(doc) //doc => actual row, return: Tuple2(String,Int)
val xy = getXYDatapoint(doc) // return: Tuple2(Int,Int)
val b = B(header._1,header._2,xy._1,xy._2)
每个继承的case类使用相同的getHeader(doc)函数来获取标头。 (这就是抽象类A有两个参数的原因)
我希望它看起来更好,以便我可以杀死一些行。
类似的东西:
val b = B(header+xy)
或者别的什么。我可以更改整个Scala代码并打开任何帮助,让它看起来更好(我是Scala的新手)
我尝试了无形但是没有用:
import shapeless._
import syntax.std.tuple._
val header = getHeader(doc)
val xy = getXY(doc)
val param = header++xy
val b = (B.apply _).tupled(param) // didn't work because param is of type prepend.Out
val b = (B.apply _).tupled(("a",2,3,4)) // would work
当有人知道一些不错的提示或技巧时,我很乐意听到它。
答案 0 :(得分:1)
您可以为案例类定义另一个apply方法:
case class B(id: String, override val time: Int, x: Int, y: Int) extends A(id, time)
object B {
def apply(header: (String, Int), coordinates: (Int, Int)): B =
B(header._1, header._2, coordinates._1, coordinates._2)
}
现在您可以将其用作:
val header = getHeader(doc)
val coords = getXY(doc)
val b = B(header, coords)
这很好,因为您不再需要调用tupled
,只需使用新的apply方法构建实例,并直接传递getHeader
和getXY
的结果。< / p>
答案 1 :(得分:1)
你真的很亲密;你只需要明确说出你想要的类型就是一个元组。以下是所有需要帮助的人的一般例子:
import shapeless.syntax.std.tuple._
case class Test(a: Int, b: Int, c: String, d: Int)
val tuple: (Int, Int, String, Int) = (1, 2) ++ ("a", 3)
Test.tupled(tuple) // works
但是,如果我可以添加,您的用例可以通过一些额外的建模来简化。然后你根本不需要没有形状。最近我看到很多人滥用案例类。它们旨在作为抽象数据类型(ADT),而不是一般意义上的类。如果你的case类需要包含一些逻辑,那么最好让它只是一个类。
但是,您确实有案例类的用例。为什么不在两个单独的ADT中捕获有关标头和数据点的信息?
这是完整的代码:
case class Header(id: String, time: Int)
case class DataPoint(x: Int, y: Int)
abstract class A(id: String, val time: Int) {
// whatever
}
class B(header: Header, dataPoint: DataPoint) extends A(header.id, header.time) {
// whatever
}
val dataPoint = DataPoint(1, 2)
val header = Header("header", 42)
val b = new B(header, dataPoint)
当然,如果类A
的参数id
和time
的语义是标题中的参数,您甚至可以A
只有一个参数:abstract class A(header: Header)
。
就个人而言,我认为这是干净,清晰和良好的模型。当然,您的意见可能会有所不同。 :)