dart-idiomatic-usage

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Dart 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
.length
checks or
.cast()
), and ensures type-safe collection transformations. Assumes a modern Dart environment with null safety enabled.
分析并重构Dart代码,使其符合官方《Effective Dart: Usage》指南,尤其针对字符串操作和集合处理场景。该规范强制推行惯用语法,通过消除反模式(如
.length
检查或
.cast()
)优化性能,同时确保集合转换的类型安全。默认运行环境为已启用空安全的现代Dart环境。

Instructions

使用说明

  1. 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';
  2. Collection Initialization
    • Replace unnamed constructor calls for
      Map
      ,
      Set
      , and
      List
      with collection literals.
    • Utilize the spread operator (
      ...
      ,
      ...?
      ) and collection
      if
      /
      for
      for dynamic collection building instead of
      .add()
      or
      .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,
    ];
  3. Collection Emptiness Checks
    • Identify any collection checks comparing
      .length
      to
      0
      .
    • Replace them with
      .isEmpty
      or
      .isNotEmpty
      .
    dart
    // BAD
    if (items.length == 0) return;
    if (items.length > 0) process(items);
    
    // GOOD
    if (items.isEmpty) return;
    if (items.isNotEmpty) process(items);
  4. Iteration Logic (Decision Tree) Evaluate how iterables are being processed and apply the following logic:
    • IF iterating over a
      Map
      -> THEN
      map.forEach((k, v) { ... })
      is acceptable.
    • IF applying an existing function (tear-off) to an
      Iterable
      -> THEN use
      iterable.forEach(functionName)
      .
    • IF executing a function literal/block on an
      Iterable
      -> THEN use a
      for-in
      loop.
    dart
    // BAD
    people.forEach((person) {
      person.greet();
    });
    
    // GOOD
    for (final person in people) {
      person.greet();
    }
    
    // GOOD (Tear-off)
    people.forEach(print);
  5. 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
      .whereType<T>()
      . Do NOT use
      .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
      .cast<T>()
      is used -> THEN refactor to avoid it. Prefer creating the collection with the correct type, casting elements on access, or eagerly casting with
      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
  6. Validate-and-Fix Loop
    • Review the refactored code.
    • Verify that no
      +
      operators remain for string concatenation.
    • Verify that
      .cast()
      is completely eliminated unless explicitly justified by lazy-evaluation requirements.
    • STOP AND ASK THE USER: If the original code relies heavily on lazy evaluation via
      .cast()
      and converting to
      List.from()
      might cause performance regressions on massive datasets, pause and ask: "Refactoring
      .cast()
      to
      List.from()
      forces eager evaluation. Is this collection large enough that we need to preserve lazy evaluation, or is eager instantiation acceptable?"
  1. 字符串拼接与插值
    • 扫描代码中使用
      +
      运算符的字符串拼接写法。
    • 相邻字符串字面量拼接改为直接相邻书写(无需运算符)。
    • 变量拼接替换为字符串插值。
    • 插值表达式中如果标识符后没有跟随字母数字字符,移除不必要的大括号。
    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';
  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,
    ];
  3. 集合空值检查
    • 识别所有将
      .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);
  4. 迭代逻辑(决策树) 评估可迭代对象的处理方式,并遵循以下逻辑:
    • 如果遍历
      Map
      -> 使用
      map.forEach((k, v) { ... })
      是可接受的。
    • 如果
      Iterable
      应用现有函数(tear-off) -> 使用
      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);
  5. 类型过滤与类型转换(决策树) 评估集合的类型转换或过滤方式:
    • 如果将可迭代对象过滤为特定类型 -> 使用
      .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
  6. 验证与修复循环
    • 审查重构后的代码。
    • 确认没有遗留用于字符串拼接的
      +
      运算符。
    • 确认
      .cast()
      已完全移除,除非有懒加载需求明确证明其合理性。
    • 停止并询问用户: 如果原始代码大量依赖
      .cast()
      的懒加载特性,转换为
      List.from()
      可能会在超大数据集上导致性能回退,请暂停并询问:"将
      .cast()
      重构为
      List.from()
      会强制立即求值。该集合的规模是否大到需要保留懒加载特性,还是可以接受立即实例化?"

Constraints

约束条件

  • DO NOT use
    Map()
    ,
    Set()
    , or
    List()
    unnamed constructors.
  • DO NOT use
    .length == 0
    or
    .length > 0
    for iterables.
  • DO NOT use
    Iterable.forEach()
    with a function literal.
  • DO NOT use
    .cast()
    when a nearby operation (like
    List.from()
    or
    .map<T>()
    ) will suffice.
  • DO NOT use
    where((e) => e is T)
    ; strictly enforce
    whereType<T>()
    .
  • DO NOT use
    +
    for string concatenation of literals or variables.
  • PREFER string interpolation (
    $variable
    ) over concatenation.
  • PREFER the spread operator (
    ...
    ) and collection-if/for over imperative
    .add()
    /
    .addAll()
    mutations.
  • 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()
    修改操作。
  • 避免在字符串插值中使用大括号,除非表达式求值或歧义消除需要。