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

问题描述 投票:0回答:4

我是 Dart 新手,刚刚学习基础知识。

Dart-Homepage 显示如下:

事实证明,Dart 确实有办法询问是否有可选的 调用方法时提供了参数。只需使用 问号参数语法。

这是一个例子:

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 编辑器已将问号标记为错误:

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 是否为空就足够了,但我想学习这门语言。

有谁知道这个问题的原因吗? 如何检查该参数是否是手动设置的?

syntax dart syntax-error
4个回答
10
投票

该功能在 Dart 开发过程中曾存在过,但再次被删除,因为它导致的复杂性比删除时还要多,而没有解决实际需要解决的问题 - 默认参数转发。

如果你有一个函数

foo([x = 42])
并且你想要一个函数转发给它
bar([x]) => f(x);
,那么,由于
foo
实际上可以判断
x
是否被传递,所以你实际上最终编写了
bar([x]) => ?x ? foo(x) : foo();
。这比没有 ?: 运算符时所要做的事情
更糟糕

提出了关于拥有

bar([x]) => foo(?:x)
或某种东西,如果 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
作为默认值就可以了,比较简单。


4
投票

我正在尝试类似的事情:

这不起作用

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

这有效

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

这也有效

widget.optionalStringParameter ?? 'default string'

0
投票

在 Dart 早期(1.0 之前),支持检查可选参数是否实际上是提供者,但由于它会引起一些麻烦而被删除。


0
投票

我有一个测试用例,其中被测对象很复杂,我需要取消一些可选字段以进行测试。问题是我正在尝试创建一个辅助函数来保持测试不那么冗长(复制和粘贴大量数据)。尝试找出如何使用此处的函数使某些字段无效。

© www.soinside.com 2019 - 2024. All rights reserved.