dart - 飞镖 | Flutter:如何在 null 安全下从 Map 传递函数?为什么需要 bang 运算符?
问题描述
背景:
我一直在研究如何使用 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 控制台如下图所示:
问题:
我认为答案很容易,但我已经为此苦苦挣扎了一段时间。我的问题是:
我只希望,“这种水果尝起来像紫色!” 已在控制台中打印,所以我必须在这里遗漏一些东西。我是从地图中正确传递这个函数,还是有一种更安全的传递方式?
我想知道为什么在调用 exec() 函数时必须使用 bang 运算符。由于我已经定义了 fruits 映射包含 <String, Function>,编译器会理解它必须存在。我错过了什么?
再次,提前感谢您的任何建议,我们非常感谢社区接受。
更新:
我使用以下代码删除了 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!
并返回void
- 打印返回值的
print
方法=> nullexec
总而言之,您正在打印print
函数的返回值。
为了使您的代码按预期运行,您应该使用
void exec(Function f) {
f();
}
要回答您的第二个问题,如果您没有将现有密钥传递给它,则Map
可以返回。null
这就是你应该使用 bang 的原因,因为Map
不能保证返回的值是非 null 的。
推荐阅读
- reactjs - componentDidMount() 中的同步操作
- azure - 使用 PowerShell 在 Azure 中更改 SQL 连接
- xml - 逐行注释“块”
- selenium - Appium驱动程序一次运行多个测试?
- azure - 无法确保 pod 容器存在:创建容器失败
- java - 无法绑定 logging.level.* 或 someproperty.*=some_value 下的属性
- spring - spring 依赖管理 gradle 插件不下载依赖
- c# - 相似的术语查询,但不相似的输出..有什么区别?
- java - renameTo 返回 true 但会创建新文件夹 android
- jquery - 下拉选择后更改表格的 CSS 类