You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何避免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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 14:50:19