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

时间:2016-07-07 11:28:15

标签: scala types

我正在尝试使用案例对象'类型作为抽象类型。我很惊讶地看到下面的(类似)代码编译:

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成为一个类型参数。

f = BarTwo设置为A时,BarOne.type如何编译?

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

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

我正在使用Scala 2.11.8。

val attributeType = ...中的def attributeType = ...替换FooOne时,

更新 FooTwo编译失败(正如预期的那样)。

3 个答案:

答案 0 :(得分:1)

我不知道这里发生了什么,但我确实让问题更加孤立。此外,它适用于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 :(得分: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 }
                                        ^

答案 2 :(得分:0)

  1. 在f中:A被解释为A&lt ;: Bar
  2. 因为当在抽象类
  3. 中定义F时,这就是A所代表的
  4. 如何覆盖抽象定义(以下内容无法编译):

    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
      }
    
    }