Dart中如何判断函数接收的参数是否为const常量?
Dart判断列表是否可修改(规避const列表运行时异常)
问题复现
默认参数为const列表时,在函数内调用修改方法会触发运行时错误:
void doStuff({List<int> list = const [1, 2, 3]}) { list.add(10); print(list); } void main() { doStuff();// 运行时错误: Cannot add to an unmodifiable list doStuff([1, 2, 3]); // 正常执行 }
说明:const是编译期语法特性,运行时不会直接暴露"是否为const声明"的属性,实际开发中我们需要判断的是列表是否支持修改操作——除const常量列表外,
List.unmodifiable()创建的不可变列表、固定长度列表调用修改方法时同样会抛出异常,以下方案可以覆盖所有这类场景。
推荐方案:防御性拷贝(零判断、无异常)
如果函数内需要修改传入的列表,最稳妥的方式是先创建可修改的副本,从根源避免异常,不需要做额外判断,性能开销极低:
void doStuff({List<int> list = const [1, 2, 3]}) { // 生成可修改的新列表,兼容所有传入类型 final mutableList = List<int>.of(list); mutableList.add(10); print(mutableList); }
可选方案:显式判断列表是否可修改
如果不想每次生成都副本,可以通过工具函数判断列表是否支持修改操作:
/// 判断列表是否支持变长修改操作 bool isMutableList(List list) { try { // 执行无副作用的试探操作:添加元素后立刻移除,不改变原列表内容 list.add(null); list.removeLast(); return true; } on UnsupportedError { // const列表、不可变列表、固定长度列表执行修改操作时都会抛出该错误 return false; } }
使用方式:
void doStuff({List<int> list = const [1, 2, 3]}) { if (isMutableList(list)) { list.add(10); print(list); } else { // 不可修改场景下的自定义逻辑,比如创建副本后修改 final newList = List<int>.of(list)..add(10); print(newList); } }
注意:不要通过runtimeType字符串匹配判断是否为不可变列表,Dart不同版本、不同编译目标(VM/JS/Wasm)的内部类型命名可能变化,会导致判断逻辑失效。
内容的提问来源于stack exchange,提问作者artzok
相关产品推荐
相关产品推荐

