【问题标题】:Referring to the type of an inner class in Scala在 Scala 中引用内部类的类型
【发布时间】:2011-01-12 03:22:53
【问题描述】:

以下代码试图模仿Polymorphic Embedding of DSLs:而不是给出Inner 中的行为,而是在其封闭类的useInner 方法中进行编码。我添加了enclosing 方法,以便用户只需要保留对Inner 实例的引用,但始终可以获得它们的封闭实例。通过这样做,来自特定Outer 实例的所有Inner 实例只绑定到一种行为(但这里需要它)。

abstract class Outer {
  sealed class Inner {
    def enclosing = Outer.this
  }
 def useInner(x:Inner) : Boolean
}

def toBoolean(x:Outer#Inner) : Boolean = x.enclosing.useInner(x)

它无法编译并且 scala 2.8 抱怨:

type mismatch; found: sandbox.Outer#Inner
               required: _81.Inner where val _81:sandbox.Outer

Programming Scala: Nested classesA Tour of Scala: Inner Classes 来看,在我看来,问题在于useInner 期望来自特定Outer 实例的Inner 实例作为参数。

什么是真正的解释以及如何解决这个问题?

【问题讨论】:

    标签: scala types inner-classes


    【解决方案1】:

    我认为 Inner 类型类似于 this.Inner 类型。 Outer#Inner 独立于外部实例(不是依赖于路径的类型)。

    abstract class Outer {
      sealed class Inner {
        def enclosing = Outer.this
      }
      def useInner(x:Outer#Inner) : Boolean
    }
    
    def toBoolean(x:Outer#Inner) : Boolean = x.enclosing.useInner(x)
    

    【讨论】:

    • 是否可以修改为toBoolean而不是useInner?
    • 如果尝试过def toBoolean(x: y.Inner forSome{val y : Outer}) : Boolean = x.enclosing.useInner(x)(Existential Types - Existential Quantification over Values from the Scala reference)但它不起作用。
    【解决方案2】:

    问题正如您所描述的那样,useInner 期待特定 Outer 实例的 Inner。由于enclosing 返回一个通用的Outer,据我所知,真的没有办法将两者联系在一起。

    但是你可以强制它:

    def toBoolean(x: Outer#Inner): Boolean = {
      val outer = x.enclosing
      outer.useInner(x.asInstanceOf[outer.Inner])
    }
    

    【讨论】:

      【解决方案3】:

      你也可以这样定义你的成员:

      def useInner(x:Outer#Inner) : Boolean
      

      或者你可以这样写:

      abstract class Outer {
          class InnerImpl {
              def enclosing = Outer.this
          }
          final type Inner = Outer#InnerImpl
          def useInner(x:Inner) : Boolean
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-05-15
        • 1970-01-01
        • 2013-11-09
        • 1970-01-01
        • 1970-01-01
        • 2023-04-02
        • 2014-06-30
        • 1970-01-01
        相关资源
        最近更新 更多