3

次の定義があるとします。

abstract class A
class B extends A

trait Test[T <: A] {
  def foo(t: T) = println("I'm Foo")

  def bar(t: T) = t match {
    case b: B => foo(b)
    case _ => println("Bar says: Other")
  }
}

Scala コンパイラーは次のエラーを出します。

<console>:14: error: type mismatch;
 found   : b.type (with underlying type B)
 required: T
           case b: B => foo(b)
                            ^

bvariable は type と同じオブジェクトでtあり、ttypeであるため、ここで何が問題なのかわかりませんT

あるいは、コンパイラは variablebを新しいものと見なします ( との関係はありませんt)。次に、bは のサブタイプですが、 の任意のサブタイプになる可能性があるためA、 のサブタイプである必要はありません。これは正しい説明ですか?TTA

4

2 に答える 2

3

case b: B実際には次のようなコードが生成されます。

if(t.isInstanceOf[B]) {
  val b = t.asInstanceOf[B]
  // ...
}

そうbではありませんt。同じインスタンスを引き続き参照しますが、の型はbisBおよび notTです。ここで同じこと:

def foo(x: String) = println(x)

foo("Foo bar".asInstanceOf[AnyRef])
<console>:9: error: type mismatch;
 found   : AnyRef
 required: String
                  foo("Foo bar".asInstanceOf[AnyRef])
于 2012-07-04T13:02:04.737 に答える
0

のすべての可能な値に対してTのサブタイプである必要があるとコンパイラに言いましたが、 の非常に具体的なサブタイプ、つまりを指定します。withがあった場合、 aを取得することを期待しますが、 a を取得するため、型が一致しません。ATABfooTest[C]class C extends BfooCB

残念ながら、新しいクラスを導入して階層を封印しなくても、コンパイラはそれを気にかけないようであるか、私が知らない他の正当な不満を持っている可能性があります。

于 2012-07-04T14:28:32.803 に答える