【问题标题】:Dart Language return on void methodDart 语言返回 void 方法
【发布时间】:2020-03-08 11:48:54
【问题描述】:

我又花了几个小时在飞镖程序中发现一个奇怪的行为。
我问我以下原因,以及在编译器级别是否有事情要做。
该代码只是关于在 Map 中设置和删除条目并跟踪删除操作:

static void removeLock(String key) {
    Lock lock = _locks.remove(key);
    if (lock !=null) return
    print ( " uniqueId $key was not locked ");
  }

地图文档说,如果该对象在删除之前就在地图中,则删除会返回该对象。
正如它所写的那样,代码一直表明密钥不在地图中。
原始错误很明显:开发人员忘记在返回后放置分号:

if (lock !=null)  return ; 

第一个问题是:为什么编译器没有检测到?

我的分析是Dart尝试返回print调用的结果,是无效的,所以用方法的签名就ok了。 QED。

问题二:有什么方法可以防止这样的错误;
为什么允许对 return 语句进行 void 函数调用?
这是一个真正的用例吗?

【问题讨论】:

  • 通常建议对所有控制结构始终使用大括号。您可以通过激活以下 Linter 提示让分析器检测丢失的括号:dart-lang.github.io/linter/lints/…
  • 我还想总体上推荐包含来自包 pedantic 或 extra_pedantic 的 Linter 提示(我个人使用最后一个)。使用此提示的优点是它们提示您的代码在结构上更一致且更具可读性。
  • 很多东西都是由不同的人推荐的,甚至经常是相互矛盾的东西。如果整个控制流结构适合一行,则 Dart 样式指南会使用 allow omitting the braces

标签: dart


【解决方案1】:

编译器没有检测到的原因是程序是有效的

正如您所推断的,在 void 函数中允许返回像 print(...) 这样的 void 表达式的结果。出于历史原因,主要允许这样做。

在 Dart 1 中,类型注释不会影响语言语义(类型是可选的),因此无论返回类型是否为 void,函数都应该以相同的方式工作。在“检查模式”下运行时,您所能得到的只是警告和一些运行时错误。因此,没有规则禁止从 void 函数返回某些内容,唯一适用的规则是您不能在同一个函数中同时拥有 return;return e; 语句,即使这只是一个警告。 因此,您可以void 函数中写入return e;,它会检查(仅在检查模式下)检查值是否为null

因此,编写了很多返回 void 表达式值的代码,尤其是像 => 函数如 void foo() => voidBody();

当迁移到 Dart 2 时,现在在编译时检查类型系统,使太多现有代码无效被认为是不可行的,因此 Dart 2 仍然允许在 void 函数中使用 return voidExpression();

【讨论】:

    猜你喜欢
    • 2021-10-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-03
    • 1970-01-01
    • 1970-01-01
    • 2012-11-24
    • 1970-01-01
    相关资源
    最近更新 更多