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

标签 flutter dart

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/

    相关文章:

    android - 在 flutter 中禁用粘贴并从 textformfield 中选择所有功能按钮

    dart - Flutter - 我正在寻找一种制作脉冲动画的方法

    angularjs - Angular Dart 中与观察者相关的令人惊讶的错误消息

    Dart:无法推断函数文字的类型,因为文字有一个 block 作为它的主体

    flutter - 流监听的竞争条件

    flutter - 为什么 AnimatedList 不使用 flutter 中的 bloc 状态列表来构建?

    flutter - 无法在列中设置 GridView

    dart - 没有 AppBar 的 Flutter TabBar

    flutter - 当 AppBar 下没有滚动内容时如何禁用 AppBar 阴影

    Dart/Flutter 页面在 SetState 后不重新加载?