2009-06-15 6 views
8

Scalaのジェネリックスの実装の詳細については不思議です。しかし、同じことは、クラス名が複数の汎用パラメータのために変更することを余儀なくされた方法をC#と比較したScalaジェネリック

class Foo0[T1]{} 
class Foo1[T1, T2]{} 

お知らせとして宣言しなければならないであろう

Scalaで
class Foo<T1>{} 
class Foo<T1, T2>{} 

:C#では1は、としてクラスを宣言することができます。 Scalaが、よりエレガントだと感じているC#の1つではなく、このルートに進むことを決めた理由はありますか?私はこれがおそらくかなり小さいニックピッキであることを知っていますが、私は推論に関してはかなり興味があります。

+0

レコードの場合、Scalaでは '{}'は必要ありません。 –

答えて

24

私はJon Skeetの答えが受け入れられたことを知っていますが、それは正しくありません。 Java言語のように、制限を強いるのはあまりJVMではありません。 Scalaは、できるだけJavaから簡単に呼び出すことができるという設計目標を持っています。Javaには、型パラメータのアーリーに基づいたクラス名のオーバーロードという概念はありません。たとえば、JVM上の型パラメータに基づいてオーバーロードを実装する簡単な方法は、名前のマングリングです。しかし、名前のマングリングはJavaから見えるようになり、醜いでしょう。あなたの例では、仮想のScalaは2つのクラスFoo_ $ 1とFoo_ $ 2をコンパイルするかもしれません。 Scalaはそのmanglingを見えなくすることができます。しかし、Javaプログラマは、そのすべての醜さを見るでしょう。

+3

私はこれがC#がとにかく何をするのかと確信しています。 Foo のタイプ名はFoo'1です。 –

4

これは、部分的にはJavaの同様の制限によるものかもしれません。私が理解しているように、Scalaはで、ほとんどはがJVM上で使用されています。

.NETポートでも、その汎用性についてはScala uses type erasureのように見えます。 (同じ記事では、Java サポートこれをしなかったので、場合でも、Scalaはうという保証がない、ScalaはJavaが本当にやった長い前に、ジェネリックを持っていたことに言及 - 。彼らは第一の特徴を設計したときにそれらが多少制限されていましたが)

+0

JVMへの変更を避けるためにちょうど賢い(多かれ少なかれ)ハックをタイプ消去していませんでしたか?もしそうなら、Scalaは実行時にジェネリックをサポートするためにJVMと全く同じ変更を必要としませんか?私はScalaがJavaよりもずっと良くなっていないと思っています。 – Joey

+0

隠しフィールドなどのように、それぞれのインスタンスにいくつかの型情報を追加しない限り、それはそうです。 「適切な」ジェネリックのようなものを、それらをサポートしていないランタイムに追加することは確かに非常に困難です。 –

+4

Scalaのジェネリックは、.NETとは異なり、より高級なものであることに注意してください。消去せずに.NETに追加する方法はわかりません。 –

2

を私は考えこれは同じ制限があるJavaへのマッピングを容易にするために行われます。

名前のマングリングを行うことは可能でしたが、Javaとの相互運用を難しくしています。私の見解では、彼らは正しい決定を下しました。

関連する問題