在编译时验证 Scala 案例 class
Validate Scala case class at compile time
我在 Scala 2.11 应用程序中有一个案例 classes,它有一个方法依赖于案例 class 的字段名称,如下所示:
final case class Foo(
val a: String,
val b: String,
val c: String
) {
def partitionColumns: Seq[String] = Seq("b", "c")
}
如果 partitionColumns
之一在案例 class 中不作为字段存在,我想要一个编译时检查来抛出错误,例如会捕获这个的东西:
final case class Bar(
val a: String,
val b: String,
val c: String
) {
def partitionColumns: Seq[String] = Seq("x", "y")
}
到目前为止,我已经将分区行为封装在一个特征中,这减少了 times/places 可能出错的次数:
sealed trait partitionedByBAndC {
def b: String
def c: String
def partitionColumns: Seq[String] = Seq("b", "c")
}
final case class Foo(
val a: String,
val b: String,
val c: String
) extends PartitionedByBAndC
但是如果trait写错了,就没有check e.g.这段代码编译得很好:
sealed trait partitionedByBAndCIncorrect {
def b: String
def c: String
def partitionColumns: Seq[String] = Seq("x", "y")
}
final case class Foo(
val a: String,
val b: String,
val c: String
) extends partitionedByBAndCIncorrect
在 Scala 2.13 中,我也许可以使用 productElementNames,但我使用的是 Scala 2.11(和 Spark 2.3)。如果不从 class/trait 中实际构造一个对象,我不确定该怎么做,这似乎有很多开销(考虑到代码中有许多这些特征)。
有一个小型库(scala-nameOf) 可以用来做这个:
final case class Foo(
val a: String,
val b: String,
val c: String
) {
import com.github.dwickern.macros.NameOf._
def partitionColumns: Seq[String] = Seq(nameOf(this.a),nameOf(this.b))
}
这不会为不属于大小写的字段编译 class
我在 Scala 2.11 应用程序中有一个案例 classes,它有一个方法依赖于案例 class 的字段名称,如下所示:
final case class Foo(
val a: String,
val b: String,
val c: String
) {
def partitionColumns: Seq[String] = Seq("b", "c")
}
如果 partitionColumns
之一在案例 class 中不作为字段存在,我想要一个编译时检查来抛出错误,例如会捕获这个的东西:
final case class Bar(
val a: String,
val b: String,
val c: String
) {
def partitionColumns: Seq[String] = Seq("x", "y")
}
到目前为止,我已经将分区行为封装在一个特征中,这减少了 times/places 可能出错的次数:
sealed trait partitionedByBAndC {
def b: String
def c: String
def partitionColumns: Seq[String] = Seq("b", "c")
}
final case class Foo(
val a: String,
val b: String,
val c: String
) extends PartitionedByBAndC
但是如果trait写错了,就没有check e.g.这段代码编译得很好:
sealed trait partitionedByBAndCIncorrect {
def b: String
def c: String
def partitionColumns: Seq[String] = Seq("x", "y")
}
final case class Foo(
val a: String,
val b: String,
val c: String
) extends partitionedByBAndCIncorrect
在 Scala 2.13 中,我也许可以使用 productElementNames,但我使用的是 Scala 2.11(和 Spark 2.3)。如果不从 class/trait 中实际构造一个对象,我不确定该怎么做,这似乎有很多开销(考虑到代码中有许多这些特征)。
有一个小型库(scala-nameOf) 可以用来做这个:
final case class Foo(
val a: String,
val b: String,
val c: String
) {
import com.github.dwickern.macros.NameOf._
def partitionColumns: Seq[String] = Seq(nameOf(this.a),nameOf(this.b))
}
这不会为不属于大小写的字段编译 class