8

Scalaジェネリックの実装の詳細について疑問に思っています。C# では、クラスを次のように宣言できます。

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

ただし、Scala では、同じことを次のように宣言する必要があります。

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

複数のジェネリック パラメーターのクラス名を強制的に変更する方法に注意してください。Scala が、私がよりエレガントだと感じる C# ではなく、このルートを選択した理由はありますか? これはおそらくかなり些細な問題であることはわかっていますが、その理由については非常に興味があります。

4

3 に答える 3

25

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

于 2009-06-15T22:05:11.023 に答える
4

Java の同様の制限が原因の 1 つかもしれません。私が理解しているように、Scala はに JVM で使用されます。JVM では、アリティによってジェネリック型をオーバーロードできません。

.NET ポートであっても、Scala はジェネリックにも型消去を使用しているようです。(同じ記事では、Scala には Java が実際にジェネリックを実装するずっと前にジェネリックがあったと述べています。そのため、Javaこれをサポートしていたとしても、Scala がジェネリックをサポートするという保証はありません。最初に機能を設計したときは、多少の制限がありました。)

于 2009-06-15T14:59:35.703 に答える
2

同じ制限があるJavaへのマッピングを容易にするために行われていると思います。

名前のマングリングを行うことも可能でしたが、Java との相互運用がより困難になるという代償がありました。私の意見では、彼らは正しい決定を下しました。

于 2009-06-15T15:00:55.840 に答える