dart + flutter:为什么编译器无法识别类型不匹配

时间:2019-06-26 16:27:04

标签: flutter dart

我将flutter应用程序的数据封装在一个名为AppData的类中。看起来像这样:

class AppData with ChangeNotifier{
  List<word.Word> _words;
  UnmodifiableListView<word.Word> words;

  AppData(){
    // at some point this will be loaded from disk
    // for now I'm just using a hardcoded list of words
    _words = word.words;

    // the following code would work:
    // words = UnmodifiableListView(_words);

    // this doesn't, but it's also not a compiler error !?
    words = _words;
  }

  // ...
}

AppData类跟踪单词列表。对于AppData的使用者,这显示为UnModifiableListView

我的代码有一个非常明显的错误:我将_words分配给words却没有将List正确地封装在UnModifiableListView中。 为什么编译器找不到此内容?

类型应该明显不匹配。来自dart docs(重点是我):

  与Java和C#中的类型系统一样,

Dart的类型系统也很完善。它   通过结合使用静态检查来增强这种健全性   (编译时错误)和运行时检查。例如,分配一个   将字符串转换为int是编译时错误。将对象转换为字符串   如果对象不是   字符串。

更新,以回复Rémi的回答:

错误消息是:

The following assertion was thrown building MultiProvider:
type 'List<Word>' is not a subtype of type 'UnmodifiableListView<Word>'

这似乎是协方差与相反的问题。

如果我知道我对List的引用实际上包含一个UnmodifiableListView,那么我可以自己进行演员表转换。 为什么编译器会为我添加隐式强制转换?

在我看来,这似乎绕过了上面文档中提到的许多类型健全性。尤其是当我更改类型层次结构并进行广泛的重构时,我依靠编译器告诉我:您混合了类型。 他们的继承树很可能在某个时候仍然是一个共同的祖先。但是它们绝对不一样。

至少对我来说,这甚至更令人惊讶,因为这不是其他“典型” OOP语言(Java,C#等)的工作方式。

所以我仍然想知道:编译器为什么找不到这个,这个设计背后的原因是什么?

1 个答案:

答案 0 :(得分:3)

实际上发生的是隐式强制转换。

由于.container { position: relative; overflow: hidden; height: 20px; width: 100px; } .content { position: absolute; height: 100%; width: 100%; background-color: red; }<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div class="container"> <div class="content"> a b c d e f g h </div> </div> <a href="#">test</a>,因此将UnmodifiableListView分配给List会自动进行强制转换。

您可以在List上将其禁用,如下所示:

UnmodifiableListView