飞镖 | Flutter:如何在 null-safety 下从 Map 传递函数?为什么需要 bang 运算符?
Dart | Flutter: How do I pass a function from a Map under null-safety? Why is a bang operator necessary?
背景:
我一直在研究如何使用 dart 代码使用 Map 传递函数。但是,我现在被难住了。在使用空安全时使用 DartPad 时,我从以下代码中得到了一个意外的空值:
void main() {
Map<String, Function> fruits = Map();
fruits['apple'] = appleDescription;
fruits['banana'] = bananaDescription;
fruits['grape'] = grapeDescription;
exec(fruits['grape']!);
}
void appleDescription() => print('This fruit tastes like red!');
void bananaDescription() => print('This fruit tastes like yellow!');
void grapeDescription() => print('This fruit tastes like purple!');
void exec(Function f) {
print(f());
}
DartPad控制台如下图所示:
问题:
我想答案会很简单,但我已经为此苦苦挣扎了一段时间。我的问题是:
我只希望 'This fruit tastes like purple!' 打印在控制台中,所以我一定在这里遗漏了一些东西。我是否从地图中正确地传递了这个函数,或者是否有一种 null 更安全的方法来传递它?
我想知道为什么在调用 exec() 函数时必须使用 bang 运算符。因为我定义了 fruits 映射包含 ,所以编译器会理解它必须存在。我错过了什么?
再次感谢社区的任何建议。
更新:
我使用以下代码删除了 bang 运算符,并在下面的答案中进行了更正:
void main() {
Map<String, Function> fruits = Map();
fruits['apple'] = appleDescription;
fruits['banana'] = bananaDescription;
fruits['cranberry'] = grapeDescription;
exec(fruits['cranberry']??= (){print('');});
}
void appleDescription() => print('This fruit tastes like red!');
void bananaDescription() => print('This fruit tastes like yellow!');
void grapeDescription() => print('This fruit tastes like purple!');
void exec(Function f) {
f();
}
您的 exec
函数尝试打印 f()
函数的结果,该函数本身会打印您正在等待的短语。
所以基本上 :
- 密码进入
exec
- 调用
f()
f()
打印 This fruit tastes like purple!
和 returns void
exec
中的 print
方法打印 return 值 => null
总而言之,您正在打印 print
函数的 return 值。
为了让您的代码按预期运行,您应该使用
void exec(Function f) {
f();
}
要回答您的第二个问题,如果您不向其传递现有密钥,Map
可以 return null
。这就是你应该使用 bang 的原因,因为不能保证 Map
的 return 是非空的。
背景:
我一直在研究如何使用 dart 代码使用 Map 传递函数。但是,我现在被难住了。在使用空安全时使用 DartPad 时,我从以下代码中得到了一个意外的空值:
void main() {
Map<String, Function> fruits = Map();
fruits['apple'] = appleDescription;
fruits['banana'] = bananaDescription;
fruits['grape'] = grapeDescription;
exec(fruits['grape']!);
}
void appleDescription() => print('This fruit tastes like red!');
void bananaDescription() => print('This fruit tastes like yellow!');
void grapeDescription() => print('This fruit tastes like purple!');
void exec(Function f) {
print(f());
}
DartPad控制台如下图所示:
问题:
我想答案会很简单,但我已经为此苦苦挣扎了一段时间。我的问题是:
我只希望 'This fruit tastes like purple!' 打印在控制台中,所以我一定在这里遗漏了一些东西。我是否从地图中正确地传递了这个函数,或者是否有一种 null 更安全的方法来传递它?
我想知道为什么在调用 exec() 函数时必须使用 bang 运算符。因为我定义了 fruits 映射包含
,所以编译器会理解它必须存在。我错过了什么?
再次感谢社区的任何建议。
更新:
我使用以下代码删除了 bang 运算符,并在下面的答案中进行了更正:
void main() {
Map<String, Function> fruits = Map();
fruits['apple'] = appleDescription;
fruits['banana'] = bananaDescription;
fruits['cranberry'] = grapeDescription;
exec(fruits['cranberry']??= (){print('');});
}
void appleDescription() => print('This fruit tastes like red!');
void bananaDescription() => print('This fruit tastes like yellow!');
void grapeDescription() => print('This fruit tastes like purple!');
void exec(Function f) {
f();
}
您的 exec
函数尝试打印 f()
函数的结果,该函数本身会打印您正在等待的短语。
所以基本上 :
- 密码进入
exec
- 调用
f()
f()
打印This fruit tastes like purple!
和 returnsvoid
exec
中的print
方法打印 return 值 => null
总而言之,您正在打印 print
函数的 return 值。
为了让您的代码按预期运行,您应该使用
void exec(Function f) {
f();
}
要回答您的第二个问题,如果您不向其传递现有密钥,Map
可以 return null
。这就是你应该使用 bang 的原因,因为不能保证 Map
的 return 是非空的。