假设一个这样的类:
sealed trait ParentTrait
sealed trait Trait1 extends ParentTrait
sealed trait Trait2 extends ParentTrait
...
case object O1 extends extends Trait1
case object O2 extends extends Trait1
....
....
case object Oi extends Trait2
case object Oj extends Trait2
case class A {
... fields ...
val someField: ParentTrait
}
如何约束函数接收具有Trait2
类型someField
的A
对象?
即
def myFunction(seq : Seq[A where A.someField is a Trait2] = {
here each item.someField in seq is a Trait2 type
}
我可能会以某种方式误解这个问题,但是如果您想约束函数以接收仅包含某些元素类型的案例类,则可以执行以下操作:
scala> :paste
// Entering paste mode (ctrl-D to finish)
sealed trait ParentTrait
sealed trait Trait1 extends ParentTrait
sealed trait Trait2 extends ParentTrait
case object O1 extends Trait1
case object O2 extends Trait1
case object Oi extends Trait2
case object Oj extends Trait2
case class A[PT <: ParentTrait](someField: PT)
def myfunc[PT <: ParentTrait](seq: Seq[A[PT]]) : Unit = ???
val st1: Seq[A[Trait1]] = Seq(A(O1), A(O2))
val st2: Seq[A[Trait2]] = Seq(A(Oi), A(Oj))
myfunc[Trait2](st2)
myfunc[Trait2](st1)
// Exiting paste mode, now interpreting.
<pastie>:31: error: type mismatch;
found : Seq[A[Trait1]]
required: Seq[A[Trait2]]
myfunc[Trait2](st1)
^
这是不可能的。类型检查在编译时完成,但someField
的具体类型在运行时之前是未知的。编译器只知道它是ParentTrait
的一个子类,它无法知道调用函数时会出现哪一个。
您可以在myFunction
中使用match
来检查您是否具有所需的类型,也可以为两种可能的someField
类型创建两个A
变体。
除非这里有充分的理由需要静态类型检查,否则我建议使用match
并让单元测试框架检测意外使用具有"错误"值someField
的函数。如果你沿着变体/泛型路线走下去,那么你的代码很快就会变得非常复杂。