Case Class 构造函数参数以元组形式给出
Case Class constructor parameter give as tuple
我的模型看起来像这样:
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 中(每个 class 都继承自 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)
每个继承案例 class 使用相同的 getHeader(doc) 函数来获取 header。 (这就是摘要 class A 有两个参数的原因)
我希望它看起来更好,这样我就可以删除一些台词。
类似于:
val b = B(header+xy)
或者别的什么。我可以更改整个 Scala 代码,并愿意寻求任何帮助,让它看起来更好(我是 Scala 的新手)
我试过 shapeless 但没用:
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
如果有人知道一些不错的提示或技巧,我会很高兴听到。
您可以为案例定义另一个应用方法 class:
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
,您只需使用新的应用方法构建实例并直接传递 getHeader
和 getXY
的结果.
你们真的很亲密;您只需要明确说明您的预期类型是一个元组。以下是所有有需要的人的一般示例:
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
但是,如果我可以补充一点,您的用例可以通过一些额外的建模来简化。那么你根本不需要无形的。最近我看到很多人滥用 classes 大小写。它们旨在作为抽象数据类型 (ADT),而不是一般意义上的 classes。如果您的案例 class 需要包含一些逻辑,那么最好将其设为 class.
不过,您确实有案例 classes 的用例。为什么不在两个单独的 ADT 中捕获有关 header 和数据点的信息?
完整代码如下:
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)
当然,如果 class A
的参数 id
和 time
的语义是来自 header 的语义,你甚至可以使 A
只接受一个参数:abstract class A(header: Header)
.
就我个人而言,我认为这是干净、清晰和 well-modelled。当然,你的看法可能不同。 :)
我的模型看起来像这样:
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 中(每个 class 都继承自 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)
每个继承案例 class 使用相同的 getHeader(doc) 函数来获取 header。 (这就是摘要 class A 有两个参数的原因)
我希望它看起来更好,这样我就可以删除一些台词。
类似于:
val b = B(header+xy)
或者别的什么。我可以更改整个 Scala 代码,并愿意寻求任何帮助,让它看起来更好(我是 Scala 的新手)
我试过 shapeless 但没用:
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
如果有人知道一些不错的提示或技巧,我会很高兴听到。
您可以为案例定义另一个应用方法 class:
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
,您只需使用新的应用方法构建实例并直接传递 getHeader
和 getXY
的结果.
你们真的很亲密;您只需要明确说明您的预期类型是一个元组。以下是所有有需要的人的一般示例:
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
但是,如果我可以补充一点,您的用例可以通过一些额外的建模来简化。那么你根本不需要无形的。最近我看到很多人滥用 classes 大小写。它们旨在作为抽象数据类型 (ADT),而不是一般意义上的 classes。如果您的案例 class 需要包含一些逻辑,那么最好将其设为 class.
不过,您确实有案例 classes 的用例。为什么不在两个单独的 ADT 中捕获有关 header 和数据点的信息?
完整代码如下:
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)
当然,如果 class A
的参数 id
和 time
的语义是来自 header 的语义,你甚至可以使 A
只接受一个参数:abstract class A(header: Header)
.
就我个人而言,我认为这是干净、清晰和 well-modelled。当然,你的看法可能不同。 :)