飞镖+颤振:为什么编译器无法识别类型不匹配



我将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类型系统,例如Java和C#中的类型系统。它 使用静态检查的组合来实现这种声音 (编译时错误(和运行时检查。例如,分配 字符串到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#,...(。

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

实际上发生了什么是隐式铸件。

因为UnmodifiableListViewList,将List分配给UnmodifiableListView进行自动铸造。

您可以在analysis_options.yaml上禁用它:

analyzer:
  strong-mode:
    implicit-casts: false

最新更新