Scala 按对象属性类型约束列表对象的类型



假设一个这样的类:

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类型someFieldA对象?

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的函数。如果你沿着变体/泛型路线走下去,那么你的代码很快就会变得非常复杂。

相关内容

  • 没有找到相关文章

最新更新