问题描述
case class Relation[T <: Model,RT] (model: T)
类型T显然是类属性“模型”的一种。 RT类型可以与T相同,也可以为List [T](取决于我们创建的OnetoOne或OnetoMany关系类型)。因此,我如何限制RT,使其不允许传递T或List [T]以外的其他内容。
PS我正在阅读有关协方差和 contravariance 的信息,但了解得并不多。在我的情况下适用吗?如果是,请提供一个例子。如果不是,请显示其他工具以达到目的。我什至不明白T和List [T]之间如何关联? T
预先感谢
解决方法
在Scala 3中,您可以使用具有广义约束的联合类型
case class Relation[T <: Model,RT](model: T)(using (RT =:= T) | (RT =:= List[T]))
例如
scala> class Model
| case class Relation[T <: Model,RT](model: T)(using (RT =:= T) | (RT =:= List[T]))
// defined class Model
// defined case class Relation
scala> val v = new Model
val v: Model = Model@51c26394
scala> Relation(v)
val res15: Relation[Model,Model] = Relation(rs$line$29$Model@51c26394)
scala> Relation[Model,List[Model]](v)
val res16: Relation[Model,List[Model]] = Relation(rs$line$29$Model@51c26394)
scala> Relation[Model,42](v)
1 |Relation[Model,42](v)
| ^
|no implicit argument of type (42 : Int) =:= Model | (42 : Int) =:= List[Model] was found for parameter x$2 of method apply in object Relation
,
考虑T <: List[T]
,List[T] <: T
和协方差,您正在尝试使用OOP /子类型多态性解决问题。
在Scala 2中,您可以尝试类型类(即席多态)
case class Relation[T <: Model,RT](model: T)(implicit sel: Selector[T,RT])
trait Selector[T <: Model,RT]
object Selector {
implicit def single[T <: Model]: Selector[T,T] = null
implicit def multiple[T <: Model]: Selector[T,List[T]] = null
}