2016-07-07 89 views
11

我想使用大小写对象的类型作为抽象类型。我很惊讶地看到(类似)的代码编译如下:如何具体设置绑定类型的抽象类型?

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

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

有没有一种方法可以为Foo的每个对象实例具体设置A


我正在使用Scala 2.11.8。


更新:,当我在FooOne & FooTwo编译与def attributeType = ...替换val attributeType = ...失败(如预期)。

+1

在'FooOne'失踪'延伸Foo'和'FooTwo'一个错字?因为如果添加它,它不会编译。 –

+0

@EndeNeu这是一个疏忽。你是对的,它不会编译(如预期)。我已经更新了这个问题,使它看起来尽可能接近实际的代码。当然这是没有用的,因为上面的代码没有编译,我的代码编译。 – muhuk

+1

@muhuk如果上面的代码没有编译,那么它不代表你的编译代码。除非你得到一个正确的最小例子,否则这个问题是无法回答的。 – Daenyth

回答

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

该错误的性质也很聪明:它是由-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 } 
             ^
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 
    } 
} 
+0

谢谢。但这不是一个答案。 – muhuk

+0

是的,我不知道如何在Stack Overflow上得到一个大的代码片段。 – robot1208

0
  1. 一个在F:A被解释为<:酒吧
  2. ,因为这时的F抽象类
  3. 定义什么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 
        } 
    
    }