2016-07-07 3 views
11

私は、ケースオブジェクトの型を抽象型として使用しようとしています。私が見てびっくりしました(同様の)以下のコードはコンパイルされます:私の本当の例Fooタイプバインドで抽象タイプを具体的に設定する方法は?

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

はパラメータ化し、ケースクラスとして使用されます。ですから、私はAを型パラメータにすることはできません。

ABarOne.typeに設定すると、f = BarTwoはどのようにコンパイルされますか?

Af: Aの場合、それはA <: Barと解釈されます。なぜそうですか?

のオブジェクトインスタンスごとにAを具体的に設定する方法はありますか?


私はScala 2.11.8を使用しています。


アップデート:私はFooOne & FooTwodef attributeType = ...val attributeType = ...を交換する際に、コンパイルが失敗した(予想通り)。

+1

は '' FooOne'と 'FooTwo'タイプミスにFoo'を拡張欠如していますか?それを追加するとコンパイルされないためです。 –

+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でコンパイルを確認しました:Fで

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. A:それはFが抽象クラス
  2. で定義されているとき、Aが何を表すかあるのでバー
  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 
        } 
    
    } 
    
関連する問題