2017-06-05 9 views
3

申し訳ありませんが、私はここで何が起こっているのか分かりませんので、これ以上の有益なタイトルや問題を策定できません。なぜこのコードはコンパイルされません:ワイルドカードを使用した型パラメータに関連する奇妙なコンパイルエラー

class Foo 
class Bar[+R <: Foo] { def bar = "bar" } 
class Bak(val b: Bar[_]) 
val bak = new Bak(new Bar[Foo]) 
bak.b.bar // fine 
println(bak.b) // fine 
bak.b // oops! 
^^^ type arguments [Any] do not conform to class Bar's type parameter bounds [+R <: Foo] 

これはなんですか?なぜ私は変数を使用できますか? 誰にも意味がありますか? ワイルドカードタイプ

+1

ワイルドカード 'class Bak(val b:Bar [_ <:Foo])'をバインドすることはできますが、なぜそれがエラーを待つのかわかりません。ワイルドカードのvalに設定しても動作しないようです。 –

+0

@MichaelZajacまあ、そうです...私は 'class Bak(val v:Bar [Foo])'を共分散のために使うこともできます。私は、この場合ワイルドカードを使用する唯一の理由は簡潔であるため、Fooを綴る必要はありませんが、境界を明示的に打ち込むことは、その目的をはっきりと破る必要があります:( – Dima

+0

'Bar [_]' –

答えて

0

共変、コンパイラは次のように、Anyresのコンテナタイプを設定します:上記のコードとして

scala> val l: List[_] = List(123) 
l: List[_] = List(123) 
scala> l 
res1: List[Any] = List(123) 
scala> :type l 
List[Any] 

Listコンテナタイプは_あり、Listためであります共変量なので、コンパイラはlresタイプをList[Any]に設定します。

そして、あなたのコードスニペットRとしてFooにをは、UpperBoundされているので、AnyFooとの間に矛盾があるでしょう:

val res: Bar[Any] = bak.b //+R <: Foo 

ので、このコンパイルエラーがthrowedされ、REPLでそれがされます自動割り当てbak.bres変数に割り当てます。

+0

これは、なぜ、それが 'Any'にセットされるのかということです。なぜなら、SLS 3.10のプレースホルダー構文によれば、デフォルトでは' Bar [_ <:Any] 'になります。この場合は 'Foo'ではなく、バグですか? – Dima

関連する問題