如何避免Dart函数调用中的代码重复?
Dart 按条件传递命名参数的优化方案
问题场景
最小复现代码
bool _flag = true; void main() { if (_flag) { apiFunction(a: 1, b: true, c: 'c'); } else { apiFunction(a: 1, b: true); } } // 无法修改且无法查看默认值的函数 void apiFunction({ int a = 0, bool b = false, String c = '', }) {...}
需求:根据_flag的值决定是否传入c: 'c',但当前写法存在代码重复,需要更简洁的实现,且不能硬编码使用未知的默认值(比如c: _flag ? 'c' : ''这种写法被禁止)。
真实场景补充
在使用cloud_firestore_odm时,生成的update()方法抽象定义如下:
Future<void> update({ int a, bool b, String c, // 其他字段... });
其内部实现通过哨兵值判断是否传入参数:
Future<void> update({ Object? a = _sentinel, Object? b = _sentinel, Object? c = _sentinel, // 其他字段... })
最优解决方案
1. 直接使用条件参数(Dart 2.17+ 推荐)
Dart 2.17版本开始支持在函数调用的参数列表中直接添加条件判断,这是最简洁直观的写法:
bool _flag = true; void main() { apiFunction( a: 1, b: true, // 只有_flag为true时才传入c参数 if (_flag) c: 'c', ); }
这种写法完全避免了代码重复,且不需要依赖任何默认值,完美适配你的场景。
2. Map展开语法(兼容低版本Dart)
如果你的项目还在使用低于2.17的Dart版本,可以用Map展开的方式实现:
void main() { // 固定参数 final baseParams = {'a': 1, 'b': true}; // 条件可选参数 final optionalParams = _flag ? {'c': 'c'} : {}; apiFunction( ...baseParams, ...optionalParams, ); }
或者更紧凑的单行写法:
void main() { apiFunction( a: 1, b: true, ...?(_flag ? {'c': 'c'} : null), ); }
注:
...?是可空展开运算符,确保当可选参数为null时不会报错。
3. 封装辅助函数(频繁使用场景)
如果这类条件传参的场景在项目中多次出现,可以封装一个辅助函数来统一处理:
void callApiWithFlag(bool flag) { final params = <String, dynamic>{ 'a': 1, 'b': true, }; if (flag) params['c'] = 'c'; apiFunction( ...params, ); } // 调用时只需传flag void main() { callApiWithFlag(_flag); }
内容的提问来源于stack exchange,提问作者iDecode
相关产品推荐
相关产品推荐

