2016-07-07 75 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 
        } 
    
    }