你不能这样做List
。中的所有元素List(c1, c2, c3, c4)
将是相同的类型,即C
以及其中之一具有类型的信息C with T
会迷路。
new C {}
, new C with T {}
是运行时值c1, c2, c3, c4
,编译器在编译时无权访问它们List(c1, c2, c3, c4)
.
你可以这样做HList
. Using shapeless.<:!<
, shapeless.ops.hlist.LiftAll
和善良的投影仪
def noElementIsSubtypeOfT[L <: HList](l: L)(implicit liftAll: LiftAll[* <:!< T, L]) = null
noElementIsSubtypeOfT(c1 :: c2 :: c3 :: HNil) // compiles
// noElementIsSubtypeOfT(c1 :: c2 :: c3 :: c4 :: HNil) // doesn't compile
Or
def noElementIsSubtypeOfT[L <: HList : LiftAll[* <:!< T, *]](l: L) = null
对于类参数你可以这样做
case class P[U <: C](c: U)(implicit ev: U <:!< T)
P(c1) // compiles
P(c2) // compiles
P(c3) // compiles
// P(c4) // doesn't compile
or
case class P[U <: C : * <:!< T](c: U)
其实,有一种方法可以用List来修复代码。你可以上课P
隐式(因此您定义隐式转换)并指定列表的类型List[P[_]](...)
(所谓的磁铁图案1 2 3 4 5 6 7, P
是一块磁铁)
implicit class P[U <: C](c: U)(implicit ev: U <:!< T)
List[P[_]](c1, c2, c3) // compiles
List[P[_]](c1, c2, c3, c4) // doesn't compile, type mismatch: found: c4.type, required: P[_]