检查 Dart 中是否提供可选参数

Checking, if optional parameter is provided in Dart

我是 Dart 的新手,只是在学习基础知识。

Dart-Homepage 显示如下:

It turns out that Dart does indeed have a way to ask if an optional parameter was provided when the method was called. Just use the question mark parameter syntax.

Here is an example:

void alignDingleArm(num axis, [num rotations]) {
  if (?rotations) {
    // the parameter was really used
  }
}

所以我写了一个简单的测试脚本来学习:

import 'dart:html';

void main() {

  String showLine(String string, {String printBefore : "Line: ", String printAfter}){
    // check, if parameter was set manually:
    if(?printBefore){
      // check, if parameter was set to null
      if(printBefore == null){
        printBefore = "";
      }
    }
    String line = printBefore + string + printAfter;
    output.appendText(line);
    output.appendHtml("<br />\n");
    return line;
  }

  showLine("Hallo Welt!",printBefore: null);

}

Dart-Editor 已经将问号标记为错误:

Multiple markers at this line
- Unexpected token '?'
- Conditions must have a static type of 
 'bool'

当运行 Dartium 中的脚本时,JS-Console 显示以下错误:

Internal error: 'http://localhost:8081/main.dart': error: line 7 pos 8: unexpected token '?'
if(?printBefore){
   ^

我知道,检查 printBefore 是否为 null 就足够了,但我想学习这门语言。

有人知道这个问题的原因吗? 如何查看是否手动设置了参数?

在早期的 Dart 时代(1.0 之前)支持检查可选参数是否实际上是提供者,但由于它会导致一些问题而被删除。

该功能在 Dart 开发的某个阶段存在,但又被删除了,因为它导致的复杂性比删除的更复杂,没有解决实际需要解决的问题——默认参数的转发。

如果你有一个函数 foo([x = 42]) 并且你想要一个函数转发给它,bar([x]) => f(x);,那么,因为 foo 实际上可以判断 x 是否被传递或者不是,你实际上最终写了 bar([x]) => ?x ? foo(x) : foo();。这比没有 ?: 运算符时更糟糕

想出了一个 bar([x]) => foo(?:x) 或一些东西,如果它存在而不是如果它不存在则在 x 上传递(我不再记得实际提议的语法),但是很快就变得复杂了,fx将命名参数转换为位置参数 - bar({x,y}) => foo(?:x, ?:y); - 如果提供了 y 而没有提供 x 会怎么样。对于自己造成的问题,这真的只是一个糟糕的解决方案。

因此,?x 功能被回滚。所有可选参数都有一个默认值,如果调用中没有匹配的参数,则传递该默认值。如果你想转发一个可选参数,你需要知道你转发到的函数的默认值。

对于大多数函数参数,声明的默认值为 null,内部 if (arg == null) arg = defaultValue; 语句修复它。也就是说null值可以直接转发,不会产生任何混淆。

一些参数有非null默认值。它主要是布尔参数,但也有其他情况。我建议对除命名布尔参数之外的所有内容使用 null(因为它们实际上是 named 而不是可选的)。至少除非有充分的理由不这样做——比如确保所有子类的方法参数具有相同的默认值(可能是一个很好的理由,也可能不是,而且应该是明智地使用)。

如果您有一个可选参数也可以接受 null 作为值...请考虑它是否真的应该是可选的,或者您是否只需要一个带有多个参数的不同函数。或者您可以引入一个不同的“缺失参数”默认值。示例:

abstract class C { foo([D something]); }
class _DMarker implements D { const _DMarker(); }
class _ActualC {
  foo([D something = const _DMarker()]) {
    if (something == const _DMarker()) {
      // No argument passed, because user cannot create a _DMarker.
    } else {
      // Argument passed, may be null.
    }
  }
}

这是一个很大的解决方法,几乎​​不值得。一般情况下,直接使用null作为默认值即可,比较简单。

我正在尝试类似的东西:

这不行

widget.optionalStringParameter ? widget.optionalStringParameter : 'default string'

这个有效

widget.optionalStringParameter != null ? widget.optionalStringParameter : 'default string'

这也有效

widget.optionalStringParameter ?? 'default string'