检查 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'
我是 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'