T 和 List[T] 的类型参数边界
Type parameter bounding for T and List[T]
我有一个案例 class 有 2 个类型参数
case class Relation[T <: Model, RT] (model: T)
类型 T 显然是 class 属性 'model' 的类型。类型 RT 可以与 T 相同,也可以是 List[T](取决于我们创建的关系类型是 OneToOne 还是 OneToMany)。那么我如何限制 RT,它不允许传递除 T 或 List[T] 之外的其他内容。
PS 我正在阅读有关 covariance 和 contravariance 的内容,但了解不多。它适用于我的情况吗?如果是,能否请您举个例子。如果没有 - 那么请展示其他工具来达到它。我什至无法理解 T 和 List[T] 之间的关系? T <: 列表[T] 或列表[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$Model@51c26394)
scala> Relation[Model, List[Model]](v)
val res16: Relation[Model, List[Model]] = Relation(rs$line$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 of method apply in object Relation
考虑 T <: List[T]
、List[T] <: T
和协方差,您正在尝试使用 OOP/subtype 多态性来解决您的问题。
在 Scala 2 中,您可以尝试一种类型 class(即席多态性)
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
}
How to define "type disjunction" (union types)?
我有一个案例 class 有 2 个类型参数
case class Relation[T <: Model, RT] (model: T)
类型 T 显然是 class 属性 'model' 的类型。类型 RT 可以与 T 相同,也可以是 List[T](取决于我们创建的关系类型是 OneToOne 还是 OneToMany)。那么我如何限制 RT,它不允许传递除 T 或 List[T] 之外的其他内容。
PS 我正在阅读有关 covariance 和 contravariance 的内容,但了解不多。它适用于我的情况吗?如果是,能否请您举个例子。如果没有 - 那么请展示其他工具来达到它。我什至无法理解 T 和 List[T] 之间的关系? T <: 列表[T] 或列表[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$Model@51c26394)
scala> Relation[Model, List[Model]](v)
val res16: Relation[Model, List[Model]] = Relation(rs$line$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 of method apply in object Relation
考虑 T <: List[T]
、List[T] <: T
和协方差,您正在尝试使用 OOP/subtype 多态性来解决您的问题。
在 Scala 2 中,您可以尝试一种类型 class(即席多态性)
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
}
How to define "type disjunction" (union types)?