3

Javaで私は書くだろう

void foo(final Set<? extends SomeClass> someObjects) { /* ... */ }

Scalaで何を書く?

def foo(someObjects : Set[AnyRef[SomeClass])

しかし、これは機能しません

4

3 に答える 3

6

このようなコードを書くことはめったにありません。その理由は、あなたの例では

void foo(final Set<? extends SomeClass> someObjects) { /* ... */ }
//                ^^^^^^^^^^
//                use-site variance annotation

バリアンス アノテーションは、コレクションへのアクセスのみが可能であり、更新はできないことを示しています。次のようにメソッドを書き直すことができる可能性が非常に高いです

void foo(final Collection<? extends SomeClass> someObjects) { /* ... */ }

つまり、セット内の要素にしかアクセスできない場合Set. scala では、これはIterableorを使用することを意味しますが、ScalaTraversableのこれらの型は型パラメーターで共変です (それらは宣言されています- これは宣言サイト分散注釈です)。したがって、使用部位の差異の注釈は必要ありません。Iterable[+A]+

def foo(itr: Iterable[SomeClass])

Set[SomeClassImpl]次に、このメソッドにa を自由に渡すことができます。

scala> trait T; class S extends T
defined trait T
defined class S

scala> def foo(itr: Iterable[T]) = println(itr.isEmpty)
foo: (itr: Iterable[T])Unit

scala> Set(new S)
res1: scala.collection.immutable.Set[S] = Set(S@e1ed5b)

scala> foo(res1)
false

scalaSet[A]が in で共変でない理由は、その入力で反変である(つまりFunction1 ) をA実装しているためです。したがって、 で不変でなければなりません。一部のチャンプが以前にこれを尋ねましたA => BooleanSet[A]A

実際、述語関数の実装の詳細Setとして使用することは、はるかに一般的です。たとえば、次のようになります。

def bar(p: SomeClass => Boolean)

このイベントでは; あなたが使用することができます:

scala> bar(res1.toSet[T])
于 2012-06-15T14:35:44.590 に答える
5

の直訳は

void foo(final Set<? extends SomeClass> someObjects) { /* ... */ }

def foo(someObjects: Set[_ <: SomeClass]) { /* ... */ }

また

def foo(someObjects: Set[_ <: SomeClass]): Unit = { /* ... */ }

Java クラスのメソッドをオーバーライドする場合は、先頭overridedef. そうでない場合は、他の回答で説明されているように、別の方法で物事を行うことを検討してください。

于 2012-06-15T18:50:24.750 に答える
3

型バインドを使用して依存関係を定義できます。

def foo[A <: SomeClass]( someObjects: Set[A] ): Unit = ...

ここでは、 を拡張A <: SomeClassすることを意味し、 のスーパークラスである必要があることを表現するために使用できます。ASomeClassB >: SomeClassBSomeClass

于 2012-06-15T14:21:12.593 に答える