键入T和List[T]的参数边界



我有一个带有2个类型参数的case类

case class Relation[T <: Model, RT] (model: T) 

类型T显然是类属性"model"的一种类型。类型RT可以与T相同,也可以是List[T](取决于我们创建OneToOne或OneToMany的关系类型(。那么,我如何限制RT,它不允许传递除T或List[T]之外的其他东西。

PS I阅读了关于协方差反方差的内容,但理解不多。它适用于我的情况吗?如果是,请提供一个例子。如果没有,那么请展示其他工具。我甚至不明白T和List[T]是如何相互联系的?T<:List[T]或List[T]<:T

提前感谢

考虑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
}

如何定义";类型析取";(联合类型(?

在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

最新更新