【问题标题】:Scala abstract type bounds cross referencingScala 抽象类型边界交叉引用
【发布时间】:2012-05-22 19:39:42
【问题描述】:

我有两个抽象类,它们将相互引用。我如何/如何对类型成员进行类型绑定,以便派生 Hex 类的 SideT 成员中的 HexT 类型始终是派生 Hex 类?所以对于派生类 HexA 保证: HexA#SideT#HexT = HexA

同样,所有派生侧类的HexT成员中的SideT类型将是派生侧类:SideB#HexT#SideT = SideB

我在 Eclipse 2.1.0.M1 和 Eclipse 3.7.2 中使用 Scala 所有类都在单独的文件中。以下编译正常,但不能保证我想要什么:

abstract class Hex { type SideT <: Side {type HexT <= Hex } }
abstract class Side { type HexT <: Hex {type SideT <= side } }
class HexC() extends Hex() { type SideT = SideC }
class SideC extends Side { type HexT = HexC }

但以下内容在派生实现中无法编译:

abstract class Hex{type SideT <: Side {type HexT = this.type}}
abstract class Side{type HexT <: Hex {type SideT = this.type}}
class HexC() extends Hex(){
  type SideT = SideC //This won't compile
}
class SideC extends Side {
  type HexT = HexC //this won't compile
}

这是正确的吗?这应该编译吗?

【问题讨论】:

    标签: scala type-bounds


    【解决方案1】:

    这个怎么样?

    abstract class Hex {
      type SideT <: Side
    }
    
    abstract class Side {
      type HexT <: Hex
    }
    
    class HexC extends Hex {
      type SideT = SideC
    }
    
    class SideC extends Side {
      type HexT = HexC
    }
    
    val evidence1 = implicitly[SideC#HexT =:= HexC]
    val evidence2 = implicitly[SideC#HexT#SideT =:= SideC]
    

    或者具有域的封装特征:

    trait abstractDomain {
      type SideT <: Side
      type HexT <: Hex
    
      abstract class Hex
      abstract class Side
    }
    
    object domain extends abstractDomain {
      type SideT = SideC
      type HexT = HexC
    
      class HexC extends Hex
      class SideC extends Side
    }
    

    或者带类型参数:

    abstract class Hex[HexT <: Hex[HexT, SideT], SideT <: Side[HexT, SideT]]
    abstract class Side[HexT <: Hex[HexT, SideT], SideT <: Side[HexT, SideT]]
    
    class HexC extends Hex[HexC, SideC]
    class SideC extends Side[HexC, SideC]
    

    【讨论】:

    • 对不起,我不明白前两个解决方案。仍然引导我对 Scala 的理解。我以前看过 =:= 组合,但找不到它的引用。有趣的是,我在 C# 中尝试了第三个月。 C# 编译器不会接受它。如果可能的话,我想在 Hex 和 Side 中使用抽象类型,尽管我将对包含它们的集合使用泛型。
    猜你喜欢
    • 2014-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-25
    • 1970-01-01
    • 2021-01-24
    • 2020-07-22
    • 2013-05-31
    相关资源
    最近更新 更多