【问题标题】:dart + flutter: why doesn't the compiler recognize type mismatchesdart + flutter:为什么编译器不能识别类型不匹配
【发布时间】:2019-06-26 16:27:04
【问题描述】:

我将 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(强调我的):

Dart 的类型系统,就像 Java 和 C# 中的类型系统一样,是可靠的。它 使用静态检查的组合来强制执行该健全性 (编译时错误)和运行时检查。例如,分配一个 String to int 是编译时错误。将对象转换为字符串 如果对象不是 字符串。

更新,回应雷米的回答:

错误信息是:

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

这似乎是协方差与逆变的问题。

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

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

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

所以我还是想知道:为什么编译器没有发现这个,这个设计背后的原因是什么?

【问题讨论】:

    标签: flutter dart


    【解决方案1】:

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

    由于UnmodifiableListViewList,因此将List 分配给UnmodifiableListView 会进行自动转换。

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

    analyzer:
      strong-mode:
        implicit-casts: false
    

    【讨论】:

      猜你喜欢
      • 2014-01-18
      • 1970-01-01
      • 1970-01-01
      • 2018-03-01
      • 2020-05-08
      • 1970-01-01
      • 2020-06-30
      • 2020-05-25
      • 1970-01-01
      相关资源
      最近更新 更多