F 绑定多态对象的集合
Collections of F-bound polymorphic objects
假设我有一个 F 界多态特征:
sealed trait FBound[Me <: FBound[Me]]
case class A() extends FBound[A]
case class B() extends FBound[B]
如果我有一个可以是任何实例的集合,我该如何使用它?
val canBeEither: Option[FBound[_]] = Some(B())
// error: type arguments [_] do not conform to trait FBound's type parameter bounds [Me <: FBound[Me]]
canBeEither.collect({ case b: B => b}).foreach(b => println("got a B!"))
你会用这个类型
T forSome { type T <: FBound[T] }
// equivalent
FBound[T] forSome { type T <: FBound[T] }
表示"some FBound
object"。你的情况
val canBeEither: Option[T forSome { type T <: FBound[T] }] = Some(B())
canBeEither.collect { case b: B => b }.foreach(println)
您可能应该始终避免将活页夹从类型构造函数应用程序中拉出。例如。 List
:
val eithers: List[T forSome { type T <: FBound[T] }]
= List[T forSome { type <: FBound[T] }](A(), B()) // ok
val eithers: List[T] forSome { type T <: FBound[T] }
= List[ThereIsNothingThatCanGoHere](A(), B()) // not ok
所以你可能想说
type SomeFBound = T forSome { type T <: FBound[T] }
并且到处使用SomeFBound
。
那就是
val canBeEither: Option[X forSome { type X <: FBound[X] }] = Some(B())
但我建议您在代码中使用它之前三思。它还会给你一堆关于存在类型的警告,你必须通过导入 scala.language.existentials
.
来消除这些警告
假设我有一个 F 界多态特征:
sealed trait FBound[Me <: FBound[Me]]
case class A() extends FBound[A]
case class B() extends FBound[B]
如果我有一个可以是任何实例的集合,我该如何使用它?
val canBeEither: Option[FBound[_]] = Some(B())
// error: type arguments [_] do not conform to trait FBound's type parameter bounds [Me <: FBound[Me]]
canBeEither.collect({ case b: B => b}).foreach(b => println("got a B!"))
你会用这个类型
T forSome { type T <: FBound[T] }
// equivalent
FBound[T] forSome { type T <: FBound[T] }
表示"some FBound
object"。你的情况
val canBeEither: Option[T forSome { type T <: FBound[T] }] = Some(B())
canBeEither.collect { case b: B => b }.foreach(println)
您可能应该始终避免将活页夹从类型构造函数应用程序中拉出。例如。 List
:
val eithers: List[T forSome { type T <: FBound[T] }]
= List[T forSome { type <: FBound[T] }](A(), B()) // ok
val eithers: List[T] forSome { type T <: FBound[T] }
= List[ThereIsNothingThatCanGoHere](A(), B()) // not ok
所以你可能想说
type SomeFBound = T forSome { type T <: FBound[T] }
并且到处使用SomeFBound
。
那就是
val canBeEither: Option[X forSome { type X <: FBound[X] }] = Some(B())
但我建议您在代码中使用它之前三思。它还会给你一堆关于存在类型的警告,你必须通过导入 scala.language.existentials
.