假设这样一个类:
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
}
如何约束一个函数来接收类型为A
的{{1}}的{{1}}对象?
即
someField
答案 0 :(得分:1)
我可能会以某种方式误解这个问题,但是如果您想约束一个函数来接收仅包含某些元素类型的案例类,则可以执行以下操作:
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)
^
答案 1 :(得分:1)
这是不可能的。类型检查在编译时完成,但是someField
的具体类型直到运行时才知道。编译器只知道它是ParentTrait
的子类,因此无法知道调用该函数时将出现哪个子类。
您可以使用match
中的myFunction
来检查是否具有所需的类型,也可以为A
的两种可能类型创建someField
的两个变体。
除非这里有强烈的理由需要静态类型检查,否则我建议使用match
并让单元测试框架检测到someField
的“错误”值对函数的意外使用。如果您遵循变体/泛型路线,那么您的代码将很快变得非常复杂。