首页 文章

如何具体设置带有类型绑定的抽象类型?

提问于
浏览
11

我试图将case对象的类型用作抽象类型 . 我惊讶地看到下面的(类似)代码编译:

sealed abstract class Bar

case object BarOne extends Bar

case object BarTwo extends Bar

sealed abstract class Foo {
  type A <: Bar

  def f: A
}

object Foo {
  object FooOne extends Foo {
    type A = BarOne.type
    val f = BarTwo
  }

  object FooTwo extends Foo {
    type A = BarTwo.type
    val f = BarOne
  }
}

在我的实例中, Foo 被参数化并用作案例类 . 所以我不能只让 A 成为一个类型参数 .

A 设置为 BarOne.type 时__74804_如何编译?

如果 f: A 中的 A 被解释为 A <: Bar ,为什么会这样呢?

有没有办法为 Foo 的每个对象实例具体设置 A


我正在使用Scala 2.11.8 .


Update: 当我用 FooOne 替换 val attributeType = ...FooOneFooTwo 编译失败(如预期的那样) .

3 回答

  • 1

    有人建议你升级到现代版的Scala吗? (玩笑 . )

    有关覆盖的错误为该类型提供了一个很好的路径 .

    $ scala
    Welcome to Scala 2.12.0-M5 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_92).
    Type in expressions for evaluation. Or try :help.
    
    scala> :pa
    // Entering paste mode (ctrl-D to finish)
    
    sealed abstract class Bar
    
    case object BarOne extends Bar
    
    case object BarTwo extends Bar
    
    sealed abstract class Foo {
      type A <: Bar
    
      def f: A
    }
    
    object Foo {
      object FooOne extends Foo {
        type A = BarOne.type
        val f = BarTwo
      }
    
      object FooTwo extends Foo {
        type A = BarTwo.type
        val f = BarOne
      }
    }
    
    // Exiting paste mode, now interpreting.
    
    <console>:26: error: overriding method f in class Foo of type => Foo.FooOne.A;
     value f has incompatible type
               val f = BarTwo
                   ^
    <console>:31: error: overriding method f in class Foo of type => Foo.FooTwo.A;
     value f has incompatible type
               val f = BarOne
                   ^
    

    该错误是this one,重复的问题是from last November .

    这个bug的本质也很聪明:它是由 -Yoverride-objects 引入的,这不是一个非常有用的选项,但在我的几个S.O.答案,现在问题 .

    编辑:

    $ scala
    Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_92).
    Type in expressions for evaluation. Or try :help.
    
    scala> object X ; object Y
    defined object X
    defined object Y
    
    scala> class C { def f: X.type = X }
    defined class C
    
    scala> class D extends C { override def f: Y.type = Y }
    defined class D
    
    scala> :quit
    $ scalam
    Welcome to Scala 2.12.0-M5 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_92).
    Type in expressions for evaluation. Or try :help.
    
    scala> scala> object X ; object Y
    
    // Detected repl transcript. Paste more, or ctrl-D to finish.
    
    defined object X
    defined object Y
    
    scala> class C { def f: X.type = X }
    defined class C
    
    scala> class D extends C { override def f: Y.type = Y }
    defined class D
    // Replaying 3 commands from transcript.
    
    scala> object X ; object Y
    defined object X
    defined object Y
    
    scala> class C { def f: X.type = X }
    defined class C
    
    scala> class D extends C { override def f: Y.type = Y }
    <console>:13: error: overriding method f in class C of type => X.type;
     method f has incompatible type
           class D extends C { override def f: Y.type = Y }
                                            ^
    
  • 0

    我不知道这里发生了什么,但我确实让问题更加孤立 . 此外,它适用于Foo子类和对象 . 我已经在scalac 2.11.8上证实了这个编译:

    object BarOne
    object BarTwo
    
    abstract class Foo[A] {
      def attributeType: A
    }
    
    object FooContainer {
      class FooOne extends Foo[BarOne.type] {
        val attributeType = BarTwo
      }
    
      object FooTwo extends Foo[BarOne.type] {
        val attributeType = BarOne
      }
    }
    
  • 1
    • 在f中:A被解释为A <:Bar

    • 因为当在抽象类中定义F时,这就是A所代表的

    • 覆盖抽象定义怎么样(下面不会编译):

    object Foo {
    
      object FooOne extends Foo {
        type A = BarOne.type
        override val f: A = BarTwo
      }
    
      object FooTwo extends Foo {
        type A = BarTwo.type
        override val f: A = BarOne
      }
    
    }
    

相关问题