Dart代码if子句后省略号(...)用法疑问,未搭配花括号是否为合法语法?
问题解答
这是Dart 2.3及以上版本的合法原生语法,是集合展开运算符和集合内置if两种特性的组合用法,专门为简化Flutter UI代码的嵌套问题设计,具体逻辑如下:
- 首先说
...(展开运算符):作用是将一个集合中的所有元素逐个拆解,插入到当前集合的对应位置。举个简单例子:List<int> listA = [1,2]; List<int> listB = [3, ...listA]; // 最终listB为 [3,1,2] - 其次是集合内置if语法:Dart允许直接在List/Map/Set的字面量定义中使用if条件判断,只有条件满足时,对应的元素才会被加入集合,不需要在集合外部单独写流程控制代码。
- 你看到的
if (state is TimerInitial)...[xxx]就是两种特性的组合:- 先判断if条件是否成立
- 条件成立时,就通过
...把后面[]里的多个按钮组件全部展开插入到Row的children列表中 - 条件不成立时,这部分组件不会被加入列表
你疑惑的「没有常规花括号」是因为这个if属于集合字面量内部的语法,不是普通的流程控制if语句,本身就不需要用花括号包裹,它的作用范围就是后面紧跟的待插入元素。
如果不使用该语法,实现同等逻辑的代码会更繁琐,嵌套层级更高:
@override Widget build(BuildContext context) { return BlocBuilder<TimerBloc, TimerState>( buildWhen: (prev, state) => prev.runtimeType != runtimeType, builder: (context, state) { // 单独构造children列表,要额外写判断和add逻辑 List<Widget> children = []; if (state is TimerInitial) { children.add(FloatingActionButton( child: Icon(Icons.play_arrow), onPressed: () => context .read<TimerBloc>() .add(TimerStarted(duration: state.duration)), )); } if (state is TimerRunInProgress) { children.add(FloatingActionButton( child: Icon(Icons.pause), onPressed: () => context.read<TimerBloc>().add(TimerPaused()), )); children.add(FloatingActionButton( child: Icon(Icons.replay), onPressed: () => context.read<TimerBloc>().add(TimerReset()), )); } if (state is TimerRunPause) { children.add(FloatingActionButton( child: Icon(Icons.play_arrow), onPressed: () => context.read<TimerBloc>().add(TimerResumed()), )); children.add(FloatingActionButton( child: Icon(Icons.replay), onPressed: () => context.read<TimerBloc>().add(TimerReset()), )); } return Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: children, ); }); }
内容的提问来源于stack exchange,提问作者Amon Chepri
相关产品推荐
相关产品推荐

