28

Scala で具体化されたジェネリックがないことは、この言語について私が最も悩まされていることです。なぜなら、単純なものは複雑な構造を使用しないと実装できないからです。

Kotlin と Ceylon の両方が具体化されたジェネリックをサポートしているため、JVM の上でそれを行うことは間違いなく可能です。以前は、Scala は JVM を変更しないとサポートできないと言われていましたが、現在、Scala 2.10 では具体化のサポートが限定的であると噂されています。だから私の質問は:

4

3 に答える 3

31

あなたの議論には欠陥があります。Kotlin はまだリリースされておらず*、Ceylon は最初のバージョンがリリースされたばかりです。発表に欠けているものの 1 つを引用します。

  • 具体化されたジェネリック

では、すみませんが、それが可能であることを証明する実装は何ですか? 実際、私は Kotlin が何を約束しているのかについてはあまり調べていませんが、Ceylonが約束しているのは、マニフェストが既に提供しているものですが、透過的な方法です。

しかし、あなたの質問で説明した問題を考えてみましょう:

trait Handles[E <: Event] {
  def handle(event: E)
}

したがって、まず第一に、JVM はインターフェイスまたはクラスの型パラメーターを識別する方法を提供しないため、JVMでチェックするE ことはできません。ただし、 Scala で次のように記述できるように、Eを実装する各オブジェクトに何を表すかに関する情報を格納できます。Handles

abstract class Handles[E <: Event : Manifest] {
  def handle(event: E)
}

次に、メソッドを見てみましょうhandle。繰り返しになりますが、JVM にはメソッド定義で型パラメーターを使用する方法がありません。これを実装する唯一の方法は、パラメーターとしてhandle受け入れることObjectです。つまり、型消去です。

Java から呼び出し可能にするhandleには、型を消去する必要があります。また、タイプが消去されている場合は、質問に記載されている制限の対象となります。これを回避する唯一の方法は、Java との互換性をなくすことです (ちなみに、これは Ceylon の最初のリリースでも利用できません)。

はい、Martin Odersky によると、Scala は 2.10 で (何らかの形で) 具体化されます。しかし、それが提供するものは何でも (そして、私は型の等価性を主張するためにマニフェストをより透過的に使用することに賭けています)、この特定の制限は JVM に固有のものであり、Java 統合を中止せずに克服することはできません。

(*) Kotlin には現在デモがあり、その具体化 (これまでのところ) は、マニフェストと instanceOf テストをバンドルするための構文糖衣にすぎません。Scala と同じ制限がすべて適用されます。

于 2011-12-22T19:24:38.283 に答える
9

https://kotlinlang.org/docs/reference/inline-functions.html#reified-type-parametersに記載されているように、Kotlin はインライン関数型パラメーターのジェネリックを具体化しました。これは Kotlin にかなり前から存在しており、すでに Kotlin エコシステム内の多くのライブラリで使用されています。ここでの他の回答は、Kotlin を参照するときに古くなっています。 Kotlin は 2016 年 2 月に 1.0 としてリリースされました。

TypeReferenceJackson で有名な Kotlin で具体化されたジェネリックの例は、 Jackson Kotlin モジュールで使用される場合、次のコードを使用します。

public inline fun <reified T: Any> ObjectMapper.readValue(jp: JsonParser): T 
     = readValue(jp, object: TypeReference<T>() {})

そして、Kotlin ベースのInjektライブラリからの同じこと:

public inline fun <reified T: Any> fullType(): FullTypeReference<T> 
    = object:FullTypeReference<T>(){}

public inline fun <reified T : Any> injectLazy(): Lazy<T> {
    return lazy { Injekt.get(fullType<T>()) }
}
于 2015-12-29T04:34:04.350 に答える
2

Andrey Breslav がこのページで言っていることによると、Kotlin には具体化された型がありません。

「はい、型パラメータはクラス オブジェクトでは使用できません」

于 2012-11-27T10:06:32.760 に答える