0

Dart2JS コンパイラ バージョン 1.0.0_r30798 (STABLE) を使用します。

サンプルコード (問題の導入のみ):

実際のコードはこちら (現在は dart2js の動作に合わせて修正されています): https://github.com/mezoni/queries/blob/master/lib/src/queries/lookup.dart

これは、 Dart 言語のクエリ可能なコレクションの一部です。

class ILookup<TKey, TElement> implements IEnumerable<IGrouping<TKey, TElement>> {
}

class Lookup<TKey, TElement> extends Object with Enumerable implements ILookup<TKey, TElement> {
}

class IEnumerable<T> implements HasIterator<T> {
}

class HasIterator<T> {
}

class IGrouping<TKey, TElement> implements IEnumerable<TKey> {
}

class Enumerable<T> implements IEnumerable<T> {
}

void main() {
  var obj = new Lookup();
  print(obj);
}

このコードは、Google Dart dart2js コンパイラの次のエラーを生成します。

 Internal Error: Inheritance of the same class with different type arguments is not
 supported: Both HasIterator<dynamic> and HasIterator<IGrouping<TKey, TElement>> are
 supertypes of Lookup<TKey, TElement>.
 class Lookup<TKey, TElement> extends Object with Enumerable implements ILookup<TKey,
 TElement> {

 ^^^^^
 Error: Compilation failed.

つまり、dart2jsコンパイラはこのコードをコンパイルできません。

だから、「これはバグなのか、機能なのか、それとも制限なのか?」ということを理解できません。

4

2 に答える 2

1

Dart Team からの回答は非常に良好です。

「VM の動作は正しく、dart2js はまだ実装していません。」

https://code.google.com/p/dart/issues/detail?id=16047#c5

Gilad Bracha からの回答も。

「FWIW、仕様にはそのような制限はありません」(RE: クラスは 2 つの異なる型パラメーターを持つインターフェイスを実装します)。

https://code.google.com/p/dart/issues/detail?id=14729#c2

また、非常によく言及されています:

「残念ながら、これは今のところ dart2js の意図的な制限です。異なる型の引数を持つ同じインターフェイスを実装することは実際にはうまくいきませんでした。そのため、人々が壊れた動作に依存することを非常に不快に感じました。」

https://code.google.com/p/dart/issues/detail?id=14729#c3

この回答は、元の質問のサンプル コードが正しく、現在 dart2js でコンパイルできないという点に完全に適合しています。

PS

私の考え(私のジャンパー):

この問題は、クラスの等価性をテストするだけでなく、型の互換性をより適切にテストすることにより、Dart2JS コンパイラで解決できると思います。

HasIterator<dynamic>この場合、 とは同じタイプではないと思います (同じクラスであっても) のパラメーターのHasIterator<IGrouping<TKey, TElement>>下限と上限を暗黙的に指定しているだけなので。TElementHasIterator<TElement>

実際には、これはここで説明できるより複雑ですが、以下を追加できます。

次の式が true であるため、これらは同じ型ではありません。

HasIterator<dynamic> != HasIterator<IGrouping<TKey, TElement>>

次の式のいずれかが真であるため、それらは競合しません (ただし、暗黙的に下限と上限を指定します)。

HasIterator<dynamic> is HasIterator<IGrouping<TKey, TElement>>
HasIterator<IGrouping<TKey, TElement>> is HasIterator<dynamic>

私たちの場合 (暗黙の) 下限はdynamicで、(暗黙の) 上限bound<IGrouping<TKey, TElement>です。

このimplicit用語は、のみを意味しresolved at compile timeます。

これは、それらの 1 つは別のサブタイプであり、コンパイラは宣言でそれらの両方を許可する必要があることを意味します。また、型注釈では、コンパイラはそれらの両方 (他のスーパー インターフェイスを含む) との互換性についてパラメーターをテストする必要があります。

Dart2JS がスーパータイプをより徹底的にテストする場合、この問題を回避できます。

ここでこれがどのように可能になるかのサンプルを提供したくはありませんが、開発者はこの問題を解決する方法を知っていると思います。

于 2014-01-13T10:06:45.683 に答える