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

scala中的循环类型参数定义

  •  4
  • paradigmatic  · 技术社区  · 15 年前

    我试图定义一个通用容器,其元素可以返回封闭容器。类似:

    abstract class Container[E <: Element] { // compile error
      def contains( e: E ): Boolean
      def addNewElement(): Unit
    }
    
    abstract class Element[C <: Container] { // compile error
      def enclosingContainer(): C
    }
    
    class MyContainer extends Container[MyElement] {
      private var elements = List[MyElement]()
      override def contains( elem: MyElement ) = elements.contains( elem )
      override def addNewElement() { elements ::= new MyElement(this) }
    }
    
    class MyElement( container: MyContainer ) extends Element[MyContainer] {
      override val enclosingContainer = container
    }
    

    但是,该代码段不能编译,因为我应该为 Element abstract class Container[E <: Element] 定义和类型 Container abstract class Element[C <: Container] 定义。

    我有一个方法来实现我正在寻找的行为?有合适的声明吗 集装箱 元素 ?我应该定义第三方对象吗?

    3 回复  |  直到 11 年前
        1
  •  6
  •   Alexey Romanov    15 年前

    已经给出的其他解决方案无法强制类型匹配:即,给定一个类型 ContainerImpl extends Container ,你应该确定 ContainerImpl.E.C 应该是 ContainerImpl 而不是其他容器。这是一个执行这一点(改编自 http://programming-scala.labs.oreilly.com/ch13.html ):

    abstract class ContainerWithElement {
      type C <: Container
      type E <: Element
    
      trait Container {
        self: C =>
        def contains( e: E ): Boolean
        def addNewElement(): Unit
      }
    
      trait Element {
        self: E =>
        def enclosingContainer(): C
      }
    }
    
        2
  •  6
  •   Daniel C. Sobral    15 年前
    abstract class Container[E <: Element[_]] {
      def contains( e: E ): Boolean
      def addNewElement(): Unit
    }
    
    abstract class Element[C <: Container[_]] {
      def enclosingContainer(): C
    }
    
    class MyContainer extends Container[MyElement] {
      private var elements = List[MyElement]()
      override def contains( elem: MyElement ) = elements.contains( elem )
      override def addNewElement() { elements ::= new MyElement(this) }
    }
    
    class MyElement( container: MyContainer ) extends Element[MyContainer] {
      override val enclosingContainer = container
    }
    
        3
  •  5
  •   Mitch Blevins    15 年前

    使用类型成员而不是类型参数可以避免以下问题:

    abstract class Container { // compile error
      type E <: Element
      def contains( e: E ): Boolean
      def addNewElement(): Unit
    }
    
    abstract class Element { // compile error
      type C <: Container
      def enclosingContainer(): C
    }
    
    class MyContainer extends Container {
      type E = MyElement
      private var elements = List[MyElement]()
      override def contains( elem: MyElement ) = elements.contains( elem )
      override def addNewElement() { elements ::= new MyElement(this) }
    }
    
    class MyElement( container: MyContainer ) extends Element {
      type C = MyContainer
      override val enclosingContainer = container
    }