web-dev-qa-db-ja.com

Scalaのジェネリック型制約を識別して説明する

私は見た <:>:<%など。誰かがこれらについて適切に説明(または検索)できますか?考えられる制約は何ですか、それらは何をしますか、そしてそれらをいつ使用するかの例は何ですか?

45
Alex Black

S <: Tは、STのサブタイプであることを意味します。これは、 upper type bound とも呼ばれます。同様に、S >: Tは、STのスーパータイプであることを意味し、 下位タイプの境界 です。

S <% Tはビューバウンドであり、Sはその値をT型の値にマップする view を備えている必要があることを表します。

私にとっても混乱を招くし、私はバークレーのプログラミング言語の修士号を持っています。

68
Raph Levien

ここには2つの異なる獣がありますが、それらはすべて「制約」ではなく「境界」として知られています...

最初は型の境界です:

  • <:-上限タイプのバインド
  • >:-型の下限

これらは基本的にJavaのsuperおよびextendsと同じであり、実際には生成されたバイトコードにそのようにエンコードされます。これは相互運用に適しています:)

次に構文糖が来ます:

  • <%-ビュー境界
  • :-バインドされたコンテキスト

これらは、Javaがおそらく理解できるような方法でエンコードされていません(ただしscalaシグネチャで表されますが、scala =コンパイラを支援するためにすべてのクラスに追加され、最終的にはScalaリフレクションライブラリ)のベースになります

これらは両方とも暗黙的なパラメーターに変換されます。

def fn[A <% B](arg: A)  = ... //sugared
def fn[A](arg: A)(implicit ev: A => B) = ... //unsugared

def fn[A : Numeric](arg: A)  = ... //sugared
def fn[A](arg: A)(implicit ev: Numeric[A]) = ... //unsugared

このため、Scalaは、関数またはコンストラクターに対して暗黙のラベルが付いた1つのブロックのみを許可するため、ビューの境界またはコンテキストの境界と独自の暗黙を組み合わせることはできません。

独自の暗黙を使用する必要がある場合は、最初にそのような境界を手動で無糖バージョンに変換し、これを暗黙ブロックに追加する必要があります。

54
Kevin Wright