代码之家  ›  专栏  ›  技术社区  ›  Avba

按对象属性类型列出对象的scala约束类型

  •  1
  • Avba  · 技术社区  · 7 年前

    假设一个类是这样的:

    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 具有 someField 类型 Trait2 ?

    def myFunction(seq : Seq[A where A.someField is a Trait2] = {
      here each item.someField in seq is a Trait2 type
    }
    
    2 回复  |  直到 7 年前
        1
  •  1
  •   Yaneeve    7 年前

    我可能误解了这个问题,但如果您希望将函数约束为接收仅包含某些元素类型的case类,则可以执行以下操作:

    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)
               ^
    
        2
  •  1
  •   Tim    7 年前

    这是不可能的。类型检查是在编译时完成的,但是 someField 直到运行时才知道。编译器只知道它是 ParentTrait

    你可以用 match 在里面 myFunction 检查您是否具有所需的类型,或创建 A 对于两种可能的 .

    除非有充分的理由需要在这里进行静态类型检查,否则我建议使用 比赛 以及让单元测试框架检测具有“错误”值的函数的意外使用 . 如果您沿着变体/泛型的路线走下去,那么您的代码将很快变得非常复杂。

    推荐文章