Uncaught (in promise) DartError: NoSuchMethodError


最近在 flutter 遇到了这个问题:

事发地点:

Future<void> main() async {
  var x;
  x = 'null';
  x?.sayhello();
}

原因很简单,变量 x 没有方法 sayhello

但是,这种问题在编辑器里竟然没有提示:

这属实有点超出我的预期了,dart 不是强类型吗?

问题出在 dynamic 上,当一个变量被声明为 dynamic 类型时,编译器不会对其进行静态类型检查,方法调用或属性访问的合法性推迟到运行时验证,这意味着:

  • 编译器允许任意方法或属性访问,而不报错。
  • 如果运行时调用了不存在的方法或属性,会抛出 NoSuchMethodError。

Dart 官方建议:

  • 尽可能使用具体类型或类型推断(如 var、final),仅在必要时使用 dynamic。
  • 在处理动态数据时,尽量通过类型转换(如 as)或解析(如 JSON 到强类型模型)恢复类型安全。

另外,可以通过添加 自定义静态检查,为编辑器增加提示。

扩展一下,dynamic 和 object 有什么区别呢?

  • Object 是所有类型的超类,变量声明为 Object 时,编译器只允许调用 Object 类的方法(如 toString)。
  • dynamic 允许调用任何方法,编译器不检查,运行时解析。
Object obj = "Hello";
print(obj.length); // 编译错误,Object 没有 length
dynamic dyn = "Hello";
print(dyn.length); // 编译通过,运行时返回 5

部分内容来自 grok