Flutter 为什么在Dart的列表定义中使用if和for?

Flutter 为什么在Dart的列表定义中使用if和for?,flutter,dart,Flutter,Dart,Dart支持在创建列表时使用“if”和“for”: var nav = [ 'Home', 'Furniture', 'Plants', if (promoActive) 'Outlet' ]; 以及: 这有什么意义?它比创建一个列表,然后像在其他编程语言中那样附加到列表中更好: var nav = [ 'Home', 'Furniture', 'Plants', ]; if (promoActive) nav.add('Outlet'); 为了更好地理解这一点

Dart支持在创建列表时使用“if”和“for”:

var nav = [
  'Home',
  'Furniture',
  'Plants',
  if (promoActive) 'Outlet'
];
以及:

这有什么意义?它比创建一个列表,然后像在其他编程语言中那样附加到列表中更好:

var nav = [
  'Home',
  'Furniture',
  'Plants',
];

if (promoActive) nav.add('Outlet');

为了更好地理解这一点,我阅读了以下建议:

颤振API设计的一个关键目标是,尽可能地 代码的文本布局反映了 生成的用户界面

看起来原因仅仅是为了flutter中的代码可读性。例如,以下代码:

var command = [
  engineDartPath,
  frontendServer,
];
for (var root in fileSystemRoots) {
  command.add('--filesystem-root=$root');
}
for (var entryPointsJson in entryPointsJsonFiles) {
  if (fileExists("$entryPointsJson.json")) {
    command.add(entryPointsJson);
  }
}
command.add(mainPath);
可改为以更简洁的形式编写:

var command = [
  engineDartPath,
  frontendServer,
  for (var root in fileSystemRoots) '--filesystem-root=$root',
  for (var entryPointsJson in entryPointsJsonFiles)
    if (fileExists("$entryPointsJson.json")) entryPointsJson,
  mainPath
];

文档中还有很多示例,但简短的回答似乎只是为了代码的可读性和简洁性。

有多个因素在起作用:

  • 演出
  • 可读性
可读性 实现此功能的主要原因是针对
列表视图
/
堆栈
和所有其他具有
子项
参数的小部件

这些小部件不支持
null
作为参数,这导致了大量的挫折(这导致了github问题:)

简言之,问题在于小部件的声明性质意味着使用
add
&co实际上不是一个选项

没有
,如果
/
用于
内部集合,我们将不得不编写:

列出子项=[
Foo(),
]
如果(条件)
添加(Bar());
返回脚手架(
正文:ListView(
儿童:儿童,,
),
);
这使得很难理解屏幕上呈现的是什么,因为构建方法现在是碎片化的

或者,我们必须写:

返回脚手架(
正文:ListView(
儿童:[
Foo(),
条件?Bar():空,
].where((e)=>e!=null).toList(),
),
);
这更具可读性,但明显缺乏灵活性,因为任何比此示例更复杂的内容都很难实现

作为解决方案,我们现在可以写:

返回脚手架(
正文:ListView(
儿童:[
Foo(),
如果(条件)
Bar(),
]
),
);
这既可读,易于编写,又不容易出错

演出 此功能的一个有趣方面是,它提高了颤振应用程序的性能

写作时要考虑的事项:

最终列表=[
Foo(),
];
如果(条件)
添加(Bar());
通过使用
add
,列表大小会随着时间的推移而变化。这意味着任何
添加
都可能导致
列表
被重新分配以支持更多项目,这是非常昂贵的

同样的问题也适用于:

ListView(
儿童:[
Foo(),
条件?Bar():空,
].where((e)=>e!=null).toList(),
)
其中,我们有效地实例化了
列表两次,并对其所有项目进行了两次迭代(一次用于
where
,另一次用于
ListView

在集合内部使用
if
/
时,不会出现这些性能问题。
写作时:

ListView(
儿童:[
Foo(),
如果(条件)
Bar(),
],
);
这会立即以正确的大小分配
列表
,如果执行一次且仅执行一次,则分配

原因是,实际上,此语法相当于:

列出子项;
如果(条件)
儿童=[
Foo(),
Bar(),
];
其他的
儿童=[
Foo(),
]
既不涉及
添加
也不涉及
其中
/
列表

var command = [
  engineDartPath,
  frontendServer,
  for (var root in fileSystemRoots) '--filesystem-root=$root',
  for (var entryPointsJson in entryPointsJsonFiles)
    if (fileExists("$entryPointsJson.json")) entryPointsJson,
  mainPath
];