dart-idiomatic-usage
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseDart Effective Strings and Collections
Dart 高效字符串与集合处理
Goal
目标
Analyzes and refactors Dart code to comply with the official "Effective Dart: Usage" guidelines specifically targeting string manipulation and collection handling. It enforces idiomatic syntax, optimizes performance by eliminating anti-patterns (like checks or ), and ensures type-safe collection transformations. Assumes a modern Dart environment with null safety enabled.
.length.cast()分析并重构Dart代码,使其符合官方《Effective Dart: Usage》指南,尤其针对字符串操作和集合处理场景。该规范强制推行惯用语法,通过消除反模式(如检查或)优化性能,同时确保集合转换的类型安全。默认运行环境为已启用空安全的现代Dart环境。
.length.cast()Instructions
使用说明
-
String Concatenation and Interpolation
- Scan the code for string concatenations using the operator.
+ - Replace adjacent string literal concatenations with adjacent strings (no operator).
- Replace variable concatenations with string interpolation.
- Remove unnecessary curly braces in interpolations where the identifier is not followed by alphanumeric text.
dart// BAD var s1 = 'Hello ' + name + '!'; var s2 = 'Hi, ${name}!'; var s3 = 'Part 1 ' + 'Part 2'; // GOOD var s1 = 'Hello $name!'; var s2 = 'Hi, $name!'; var s3 = 'Part 1 ' 'Part 2'; - Scan the code for string concatenations using the
-
Collection Initialization
- Replace unnamed constructor calls for ,
Map, andSetwith collection literals.List - Utilize the spread operator (,
...) and collection...?/iffor dynamic collection building instead offoror.add()..addAll()
dart// BAD var addresses = Map<String, Address>(); var counts = Set<int>(); var args = <String>[]; args.addAll(options); if (flag != null) args.add(flag); // GOOD var addresses = <String, Address>{}; var counts = <int>{}; var args = [ ...options, if (flag != null) flag, ]; - Replace unnamed constructor calls for
-
Collection Emptiness Checks
- Identify any collection checks comparing to
.length.0 - Replace them with or
.isEmpty..isNotEmpty
dart// BAD if (items.length == 0) return; if (items.length > 0) process(items); // GOOD if (items.isEmpty) return; if (items.isNotEmpty) process(items); - Identify any collection checks comparing
-
Iteration Logic (Decision Tree) Evaluate how iterables are being processed and apply the following logic:
- IF iterating over a -> THEN
Mapis acceptable.map.forEach((k, v) { ... }) - IF applying an existing function (tear-off) to an -> THEN use
Iterable.iterable.forEach(functionName) - IF executing a function literal/block on an -> THEN use a
Iterableloop.for-in
dart// BAD people.forEach((person) { person.greet(); }); // GOOD for (final person in people) { person.greet(); } // GOOD (Tear-off) people.forEach(print); - IF iterating over a
-
Type Filtering and Casting (Decision Tree) Evaluate how collections are transformed or filtered by type:
- IF filtering an iterable to a specific type -> THEN use . Do NOT use
.whereType<T>()..where((e) => e is T) - IF copying an iterable while preserving its original type -> THEN use .
.toList() - IF copying an iterable and changing its type -> THEN use .
List<T>.from(iterable) - IF is used -> THEN refactor to avoid it. Prefer creating the collection with the correct type, casting elements on access, or eagerly casting with
.cast<T>().List<T>.from()
dart// BAD var ints = objects.where((e) => e is int).cast<int>(); var copy = List.from(iterable); // when type change isn't needed var casted = objects.cast<int>(); // GOOD var ints = objects.whereType<int>(); var copy = iterable.toList(); var casted = List<int>.from(objects); // Eager cast - IF filtering an iterable to a specific type -> THEN use
-
Validate-and-Fix Loop
- Review the refactored code.
- Verify that no operators remain for string concatenation.
+ - Verify that is completely eliminated unless explicitly justified by lazy-evaluation requirements.
.cast() - STOP AND ASK THE USER: If the original code relies heavily on lazy evaluation via and converting to
.cast()might cause performance regressions on massive datasets, pause and ask: "RefactoringList.from()to.cast()forces eager evaluation. Is this collection large enough that we need to preserve lazy evaluation, or is eager instantiation acceptable?"List.from()
-
字符串拼接与插值
- 扫描代码中使用运算符的字符串拼接写法。
+ - 相邻字符串字面量拼接改为直接相邻书写(无需运算符)。
- 变量拼接替换为字符串插值。
- 插值表达式中如果标识符后没有跟随字母数字字符,移除不必要的大括号。
dart// BAD var s1 = 'Hello ' + name + '!'; var s2 = 'Hi, ${name}!'; var s3 = 'Part 1 ' + 'Part 2'; // GOOD var s1 = 'Hello $name!'; var s2 = 'Hi, $name!'; var s3 = 'Part 1 ' 'Part 2'; - 扫描代码中使用
-
集合初始化
- 将、
Map和Set的无命名构造函数调用替换为集合字面量。List - 使用展开运算符(、
...)和集合...?/if语法动态构建集合,替代for或.add()。.addAll()
dart// BAD var addresses = Map<String, Address>(); var counts = Set<int>(); var args = <String>[]; args.addAll(options); if (flag != null) args.add(flag); // GOOD var addresses = <String, Address>{}; var counts = <int>{}; var args = [ ...options, if (flag != null) flag, ]; - 将
-
集合空值检查
- 识别所有将与
.length比较的集合检查逻辑。0 - 替换为或
.isEmpty。.isNotEmpty
dart// BAD if (items.length == 0) return; if (items.length > 0) process(items); // GOOD if (items.isEmpty) return; if (items.isNotEmpty) process(items); - 识别所有将
-
迭代逻辑(决策树) 评估可迭代对象的处理方式,并遵循以下逻辑:
- 如果遍历-> 则使用
Map是可接受的。map.forEach((k, v) { ... }) - 如果对应用现有函数(tear-off) -> 则使用
Iterable。iterable.forEach(functionName) - 如果对执行函数字面量/代码块 -> 则使用
Iterable循环。for-in
dart// BAD people.forEach((person) { person.greet(); }); // GOOD for (final person in people) { person.greet(); } // GOOD (Tear-off) people.forEach(print); - 如果遍历
-
类型过滤与类型转换(决策树) 评估集合的类型转换或过滤方式:
- 如果将可迭代对象过滤为特定类型 -> 则使用,禁止使用
.whereType<T>()。.where((e) => e is T) - 如果复制可迭代对象并保留其原始类型 -> 则使用。
.toList() - 如果复制可迭代对象并更改其类型 -> 则使用。
List<T>.from(iterable) - 如果使用了-> 则重构代码避免使用。优先使用正确类型创建集合、访问元素时转换,或使用
.cast<T>()进行立即类型转换。List<T>.from()
dart// BAD var ints = objects.where((e) => e is int).cast<int>(); var copy = List.from(iterable); // when type change isn't needed var casted = objects.cast<int>(); // GOOD var ints = objects.whereType<int>(); var copy = iterable.toList(); var casted = List<int>.from(objects); // Eager cast - 如果将可迭代对象过滤为特定类型 -> 则使用
-
验证与修复循环
- 审查重构后的代码。
- 确认没有遗留用于字符串拼接的运算符。
+ - 确认已完全移除,除非有懒加载需求明确证明其合理性。
.cast() - 停止并询问用户: 如果原始代码大量依赖的懒加载特性,转换为
.cast()可能会在超大数据集上导致性能回退,请暂停并询问:"将List.from()重构为.cast()会强制立即求值。该集合的规模是否大到需要保留懒加载特性,还是可以接受立即实例化?"List.from()
Constraints
约束条件
- DO NOT use ,
Map(), orSet()unnamed constructors.List() - DO NOT use or
.length == 0for iterables..length > 0 - DO NOT use with a function literal.
Iterable.forEach() - DO NOT use when a nearby operation (like
.cast()orList.from()) will suffice..map<T>() - DO NOT use ; strictly enforce
where((e) => e is T).whereType<T>() - DO NOT use for string concatenation of literals or variables.
+ - PREFER string interpolation () over concatenation.
$variable - PREFER the spread operator () and collection-if/for over imperative
.../.add()mutations..addAll() - AVOID curly braces in string interpolation unless required for expression evaluation or disambiguation.
- 禁止使用、
Map()或Set()无命名构造函数。List() - 禁止对可迭代对象使用或
.length == 0判断。.length > 0 - 禁止对传入函数字面量。
Iterable.forEach() - 当或
List.from()等就近操作可满足需求时,禁止使用.map<T>()。.cast() - 禁止使用;严格要求使用
where((e) => e is T)。whereType<T>() - 禁止使用拼接字面量或变量字符串。
+ - 优先使用字符串插值()而非拼接。
$variable - 优先使用展开运算符()和集合if/for语法,而非命令式的
.../.add()修改操作。.addAll() - 避免在字符串插值中使用大括号,除非表达式求值或歧义消除需要。