Dart支持在创建列表期间使用“if”和“for”:
var nav = [
'Home',
'Furniture',
'Plants',
if (promoActive) 'Outlet'
];
和:var listOfInts = [1, 2, 3];
var listOfStrings = [
'#0',
for (var i in listOfInts) '#$i'
];
assert(listOfStrings[1] == '#1');
这有什么意义呢?与创建列表并在其后像在其他编程语言中一样追加到列表之后相比,它有什么好处?var nav = [
'Home',
'Furniture',
'Plants',
];
if (promoActive) nav.add('Outlet');
最佳答案
有多个因素在起作用:
可读性
实现此功能的主要原因是
ListView
/ Stack
以及所有其他带有children
参数的小部件。这些小部件不支持将
null
作为参数,这导致了很大的挫败感(这导致了github问题:Allow null values in child
or children[]
collections to signal that an element should not be drawn)简而言之,问题在于小部件的声明性质意味着使用
add
&co并不是真正的选择。如果集合中没有
if
/ for
,我们将不得不编写:List<Widget> children = [
Foo(),
]
if (condition)
children.add(Bar());
return Scaffold(
body: ListView(
children: children,
),
);
由于构建方法现在是零散的,因此很难理解屏幕上呈现的内容或者,我们将不得不写:
return Scaffold(
body: ListView(
children: [
Foo(),
condition ? Bar() : null,
].where((e) => e != null).toList(),
),
);
这更具可读性,但由于缺乏比该示例更复杂的内容而很难实现灵活性作为解决方案,我们现在可以编写:
return Scaffold(
body: ListView(
children: [
Foo(),
if (condition)
Bar(),
]
),
);
这既可读又易于编写,而且不容易出错。性能
此功能一个有趣的方面是,它可以提高Flutter应用程序的性能。
关于写作时要考虑的事情:
final list = <Widget>[
Foo(),
];
if (condition)
list.add(Bar());
是通过使用add
,列表大小随时间变化。这意味着任何add
都可能会导致List
重新分配以支持更多项目,这很昂贵。相同的问题适用于:
ListView(
children: [
Foo(),
condition ? Bar() : null,
].where((e) => e != null).toList(),
)
在这里,我们有效地实例化了List
两次,并且两次遍历了所有项(一次是where
,另一次是ListView
)在集合内使用
if
/ for
时,不会发生这些性能问题。撰写时:
ListView(
children: [
Foo(),
if (condition)
Bar(),
],
);
这会立即分配正确大小的List
,如果执行一次且仅执行一次,则分配。原因是,实际上此语法等效于:
List<Widget> children;
if (condition)
children = [
Foo(),
Bar(),
];
else
children = [
Foo(),
]
这既不涉及add
也不涉及where
/ toList
关于flutter - 为什么在Dart的列表定义中使用if和for?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63388331/