1

与えられた:

class Invar[T]
trait ExtendsAnyref extends AnyRef
def f(a: Invar[ExtendsAnyref]) = {}

以下は誤りです

scala> val x: Function1[Invar[_ <: AnyRef], Unit] = f
<console>:13: error: type mismatch;
 found   : Invar[ExtendsAnyref] => Unit
 required: Invar[_ <: AnyRef] => Unit
       val x: Function1[Invar[_ <: AnyRef], Unit] = f
                                                    ^

なんで?

Scala では、ジェネリック型にはデフォルトで非バリアント サブタイプがあることを理解しています。したがって、この例のコンテキストではInvar、異なる型パラメーターを持つ のインスタンスが互いにサブタイプの関係になることはありません。したがって、Invar[ExtendsAnyref]は として使用できませんInvar[AnyRef]

しかし、「型階層の _ <: AnyRef下にある型」を意味すると理解した意味について混乱しています。は型階層の下にある型なので、に準拠することが期待されます。AnyRefExtendsAnyrefAnyRefInvar[ExtendsAnyref]Invar[_ <: AnyRef]

関数オブジェクトは入力パラメーターの型が反変であることは理解していますが、明らかに間違って理解したのでInvar[_ <: AnyRef]はなくInvar[AnyRef]使用しているため、上限の使用には「Invarパラメーター化Anyrefまたはその拡張」という意味があります。

私は何が欠けていますか?

4

1 に答える 1

1

あなたが書くとき

val x: Function1[Invar[_ <: AnyRef], Unit] = ...

これは、任意のxを受け入れる必要があることを意味します。つまり、、 などを受け入れる必要があります。明らかにそうではありません。受け入れるだけです。 Invar[_ <: AnyRef]Invar[AnyRef]Invar[String]fInvar[ExtendsAnyref]

つまり、最後の 2 つの段落を組み合わせる必要があります。関数は引数の型が反変であるため、Function1[Invar[ExtendsAnyref], Unit]に準拠するにはに準拠するFunction1[Invar[_ <: AnyRef], Unit]必要があり、その逆ではありません。Invar[_ <: AnyRef]Invar[ExtendsAnyref]

もし、あんたが

AnyRef の任意のサブクラスでパラメータ化された Invar を取る関数が必要

これは次のように記述できますFunction1[Invar[A], Unit] forSome { type A <: AnyRef }。ただし、このタイプのオブジェクトでできることは何もないと思います。1) 関数でできることは、それを引数に適用することだけですが、2) 何がわからないからです。この関数が受け入れる引数。

于 2016-06-12T19:22:05.747 に答える