Parsing Dart2JS编译器无法编译代码。这是错误、功能还是限制?

Parsing Dart2JS编译器无法编译代码。这是错误、功能还是限制?,parsing,compiler-construction,dart,standards-compliance,maturity,Parsing,Compiler Construction,Dart,Standards Compliance,Maturity,我使用Dart2JS编译器版本1.0.0U r30798(稳定) 示例代码(仅用于介绍问题): 此处的真实代码(现在已更正为dart2js行为): 这是我们的一部分 类ILookup实现IEnumerable{ } 类查找使用可枚举实现ILookup扩展对象{ } 类IEnumerable实现HasIterator{ } 类迭代器{ } 类I分组实现IEnumerable{ } 类可枚举实现IEnumerable{ } void main(){ var obj=新查找(); 打印(obj);

我使用Dart2JS编译器版本1.0.0U r30798(稳定)

示例代码(仅用于介绍问题):

此处的真实代码(现在已更正为dart2js行为):

这是我们的一部分

类ILookup实现IEnumerable{ } 类查找使用可枚举实现ILookup扩展对象{ } 类IEnumerable实现HasIterator{ } 类迭代器{ } 类I分组实现IEnumerable{ } 类可枚举实现IEnumerable{ } void main(){ var obj=新查找(); 打印(obj); } 此代码生成Google Dart dart2js编译器的以下错误:

内部错误:不允许继承具有不同类型参数的同一类
支持:HasIterator和HasIterator都是
查找的超类型。
类查找使用可枚举实现ILookup扩展对象{
^^^^^
错误:编译失败。
也就是说,
dart2js
编译器无法编译此代码


因此,我无法理解:“这是错误、功能还是限制?”。

首先,dart2js不是语言规范适用的Dart VM编译器。因为Dart VM和Javascript是不同的语言,在非常抽象的情况下可能会发生不同的行为或限制。它们不应该,但它们确实存在

话虽如此,我还是不明白为什么这段代码首先能够在VM中运行。根据我对Dart中的继承和混合的所有了解,您对
查找的定义应该如下所示:

类查找使用可枚举实现ILookup扩展对象`

因为否则,正如错误消息所说,您将使用不同的类型参数继承HasIterator两次,这当然是一个小问题-如果您最终向HasIterator添加方法,那么应该调用这两个方法中的哪一个?
method1(动态)
method1(IGrouping)

首先,dart2js不是语言规范适用的Dart VM编译器。因为Dart VM和Javascript是不同的语言,在非常抽象的情况下可能会出现不同的行为或限制。它们不应该,但它们确实存在

话虽如此,我还是不明白为什么这段代码首先能够在VM中运行。根据我对Dart中的继承和混合的所有了解,您对
查找的定义应该如下所示:

类查找使用可枚举实现ILookup扩展对象`

因为否则,正如错误消息所说,您将使用不同的类型参数继承HasIterator两次,这当然是一个小问题-如果您最终向HasIterator添加方法,那么应该调用这两个方法中的哪一个?
method1(动态)
method1(IGrouping)

Dart团队的回答非常好

VM行为是正确的,dart2js尚未实现它

也有吉拉德·布拉卡的回答

“FWIW,规范没有这样的限制”(RE:class实现了一个具有两个不同类型参数的接口)

还非常好地提到:

“不幸的是,目前这是dart2js中的故意限制。用不同类型的参数实现同一接口从未真正起作用,因此,让人们依赖于破坏的行为,我们感到非常不舒服。”

这个答案完全符合原始问题中的示例代码是正确的,目前无法通过dart2js进行编译

附言

我的想法(我的跳投):

我认为这个问题可以在Dart2JS编译器中通过更好的类型兼容性测试来解决,而不仅仅是通过测试类的相等性

我认为在这种情况下,
HasIterator
HasIterator
不是相同的类型(即使它们是相同的类),因为它们都隐式地指定了
HasIterator
TElement
参数的上下限

在实践中,这更复杂,我可以在这里解释,但我可以补充以下内容

它们的类型不同,因为此表达式为true:

HasIterator!=HasIterator
它们不冲突(但隐式指定下限和上限),因为以下表达式中的一个为真

HasIterator是HasIterator
HasIterator是HasIterator

我们的案例(隐式)下限是动态的,而(隐式)上限是动态的,Dart团队的回答非常好

VM行为是正确的,dart2js尚未实现它

也有吉拉德·布拉卡的回答

“FWIW,规范没有这样的限制”(RE:class实现了一个具有两个不同类型参数的接口)

还非常好地提到:

“不幸的是,目前这是dart2js中的故意限制。用不同类型的参数实现同一接口从未真正起作用,因此,让人们依赖于破坏的行为,我们感到非常不舒服。”

这个答案完全符合原始问题中的示例代码是正确的,目前无法通过dart2js进行编译

附言

我的想法(我的跳投):

我认为这个问题可以在Dart2JS编译器中通过更好的类型兼容性测试来解决,而不仅仅是通过测试类的相等性

我认为在这种情况下,
HasIterator
HasIterator
不是相同的类型(即使它们是相同的类),因为它们都隐式地指定了
HasIterator
TElement
参数的上下限

在实践中,这更复杂,我可以在这里解释,但我可以补充以下内容

它们的类型不同,因为此表达式为true:

HasIterator!=HasIterator