如何用特定元组限制 class 类型参数? (斯卡拉 2.10.4)
How to limit class type parameter with specific tuples? (Scala 2.10.4)
我想将类型 [R] 限制为仅在某处列出的特定元组。我的主要目标是:如果将任何其他元组而不是预期的元组传递给以下特征,确保编译器引发错误。
trait QV_Storable[R <: QV_Cue] {
val prefix: String
val tableName = prefix.concat(Random.alphanumeric take 8 mkString)
def Make(rows: Iterable[R.storageColumns]): String
}
那么我希望 QV_Storable
只接受 SegmentCue
中列出的元组,因为它是 QV_Cue
的子组。请注意,我将 R.storageColumns
传递给了 Make(rows: Iterable[R.storageColumns])
。因此,我确实希望有一种方法来访问 class 类型的参数。
trait QV_Cue{
type storageColumns <: Product
type metaColumns <: Product
}
object SegmentCue extends QV_Cue {
type storageCols = (CoreDataID, String)
type metaCols = (Int, String, Date, Int)
}
有没有这样限制的?
从 Tuple1、Tuple3 等进行子类型不是很好
您可以提供一个类型 class,只有足够的元组才能实现:
trait Ok[T] {}
// (Int, Int) is Ok
implicit val tupleIntIntOk: Ok[(Int, Int)] = new Ok[(Int, Int)] {}
// (String, _) is Ok too
implicit def tupleStringAOk[A]: Ok[(String, A)] = new Ok[(String, A)] {}
trait QV_Storable[R] {
def method(implicit rok: Ok[R]): Unit
// ...
}
在这种情况下,如果作用域中没有 rok
正确类型的值,则无法调用 QV_Storable.method
。
通过这种方式,您可以使用任何 R
创建 QV_Storable,但如果没有正确的 Ok
.
,则无法实际使用任何
有点不同的方法是在类型级别上使用类似的技巧。然而没有隐含的解决方案:
sealed trait Ok[T] {}
case class TupleIntIntOk() extends Ok[(Int, Int)]
case class TupleStringAOk[A]() extends Ok[(String, A)]
trait QV_Storable[R, OkR <: Ok[R]] {
val prefix: String
// ...
}
// compiles
val foo = new QV_Storable[(Int, Int), TupleIntIntOk] { val prefix = "xy" }
// doesn't
val bar = new QV_Storable[(Int, String), /* nothing to put here */] { val prefix = "bar "}
我想将类型 [R] 限制为仅在某处列出的特定元组。我的主要目标是:如果将任何其他元组而不是预期的元组传递给以下特征,确保编译器引发错误。
trait QV_Storable[R <: QV_Cue] {
val prefix: String
val tableName = prefix.concat(Random.alphanumeric take 8 mkString)
def Make(rows: Iterable[R.storageColumns]): String
}
那么我希望 QV_Storable
只接受 SegmentCue
中列出的元组,因为它是 QV_Cue
的子组。请注意,我将 R.storageColumns
传递给了 Make(rows: Iterable[R.storageColumns])
。因此,我确实希望有一种方法来访问 class 类型的参数。
trait QV_Cue{
type storageColumns <: Product
type metaColumns <: Product
}
object SegmentCue extends QV_Cue {
type storageCols = (CoreDataID, String)
type metaCols = (Int, String, Date, Int)
}
有没有这样限制的? 从 Tuple1、Tuple3 等进行子类型不是很好
您可以提供一个类型 class,只有足够的元组才能实现:
trait Ok[T] {}
// (Int, Int) is Ok
implicit val tupleIntIntOk: Ok[(Int, Int)] = new Ok[(Int, Int)] {}
// (String, _) is Ok too
implicit def tupleStringAOk[A]: Ok[(String, A)] = new Ok[(String, A)] {}
trait QV_Storable[R] {
def method(implicit rok: Ok[R]): Unit
// ...
}
在这种情况下,如果作用域中没有 rok
正确类型的值,则无法调用 QV_Storable.method
。
通过这种方式,您可以使用任何 R
创建 QV_Storable,但如果没有正确的 Ok
.
有点不同的方法是在类型级别上使用类似的技巧。然而没有隐含的解决方案:
sealed trait Ok[T] {}
case class TupleIntIntOk() extends Ok[(Int, Int)]
case class TupleStringAOk[A]() extends Ok[(String, A)]
trait QV_Storable[R, OkR <: Ok[R]] {
val prefix: String
// ...
}
// compiles
val foo = new QV_Storable[(Int, Int), TupleIntIntOk] { val prefix = "xy" }
// doesn't
val bar = new QV_Storable[(Int, String), /* nothing to put here */] { val prefix = "bar "}