mcpField
D
dart-idiomatic-usage

dart-idiomatic-usage

github.com/dart-lang開発53266 回インストール2 週間前に更新
リポジトリ

dart-idiomatic-usage について

Dart で慣用的な文字列やコレクションを書くためのスキルです。簡潔な構築、反復処理、型の扱いと、既存コードのリファクタリング手順を扱います。

主な機能

  1. 01文字列補間とリテラルの連結
  2. 02スプレッドと制御構文によるコレクション構築
  3. 03空判定と反復処理の効率化
  4. 04コレクションの型変換指針
  5. 05既存コレクションのリファクタリング手順

活用シーン

  1. 01Dart コードの文字列連結のリファクタリング
  2. 02命令型のコレクション構築の置き換え
  3. 03既存のコレクション操作やキャストの更新

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/dart-lang/skills --skill dart-idiomatic-usage

インストール後、Claude Code で/dart-idiomatic-usageを入力して読み込まれたか確認します。

詳細

慣用的な Dart のコレクションと文字列の記述

目次

文字列の組み立て

文字列を効率的かつ読みやすく組み立てるには、次のプラクティスに従ってください。

  • 隣接する文字列で連結する: 文字列リテラルの連結に + 演算子を使用しないでください。文字列を並べて、ひとつの文字列として記述します。
  • 文字列補間を優先する: 文字列や値を組み立てるときは、連結(+)ではなく $variable または ${expression} を使用します。
  • 不要な波括弧を省略する: 単純な識別子の直後に英数字が続かない場合は、${identifier} ではなく $identifier を使用します。
例

推奨:

// Adjacent strings
raiseAlarm(
  'ERROR: Parts of the spaceship are on fire. Other '
  'parts are overrun by martians. Unclear which are which.',
);

// Interpolation without unnecessary braces
var greeting = 'Hi, $name! I love your ${decade}s costume.';

非推奨:

// Do not use + for literals or variables
raiseAlarm(
  'ERROR: Parts of the spaceship are on fire. Other ' +
  'parts are overrun by martians. Unclear which are which.',
);

var greeting = 'Hi, ' + name + '! I love your ' + decade.toString() + 's costume.';
var badBraces = 'Hi, ${name}!';

コレクションの初期化

Dart に組み込まれている構文を活用して、コレクションを作成し、構成します。

  • コレクションリテラルを使用する: 名前なしコンストラクター(例:Map()、Set())ではなく、[]、{}、<Type>{} を使ってリスト、マップ、セットをインスタンス化します。
  • スプレッド演算子と制御フロー演算子を使用する: add() や addAll() のような命令型の呼び出しではなく、スプレッド演算子(...、...?)とコレクション内の if/for を使って動的なコレクションを構築します。
例

推奨:

var points = <Point>[];
var addresses = <String, Address>{};

var arguments = [
  ...options,
  command,
  ...?modeFlags,
  for (var path in filePaths)
    if (path.endsWith('.dart')) path.replaceAll('.dart', '.js'),
];

非推奨:

var addresses = Map<String, Address>();

var arguments = <String>[];
arguments.addAll(options);
arguments.add(command);
if (modeFlags != null) arguments.addAll(modeFlags);

コレクションの操作

コレクションの検索と反復処理を最適化します。

  • .isEmpty と .isNotEmpty を使用する: コレクションの .length が 0 または > 0 かどうかを決して確認しないでください。Iterable の契約では、長さの計算が定数時間であることは保証されません。
  • 関数リテラルを使った Iterable.forEach() は避ける: シーケンスを反復処理する際は、標準的な for-in ループを使用します。forEach() は既存関数のティアオフを渡す場合(例:people.forEach(print))に使用します。
  • whereType<T>() を使用する: where((e) => e is T) ではなく、組み込みの whereType<T>() メソッドを使って、型によってコレクションをフィルタリングします。
例

推奨:

if (lunchBox.isEmpty) return 'so hungry...';

for (final person in people) {
  process(person);
}

var ints = objects.whereType<int>();

非推奨:

if (lunchBox.length == 0) return 'so hungry...';

people.forEach((person) {
  process(person);
});

var ints = objects.where((e) => e is int).cast<int>();

コレクションの型キャスト

.cast<T>() は、操作のたびに要素の型を確認する遅延コレクションを作成し、パフォーマンスを低下させるため、使用を最小限に抑えてください。

  • 正しい型で作成する: インスタンス化時に、コレクションを正しいジェネリック型で定義します。
  • List.from() を使って即時にキャストする: コレクションを変換する必要があり、その要素の大半にアクセスする場合は、List<T>.from(iterable) または Map<K, V>.from(map) を使って、要素を一度に即時キャストします。
  • .toList() で型を維持する: 元の型を維持したままイテラブルをコピーする場合は、.toList() を使用します。List.from() は、意図的に型を変更する場合にのみ使用します。
例

推奨:

// Eager cast
var stuff = <dynamic>[1, 2];
var ints = List<int>.from(stuff);

// Map with explicit type
var reciprocals = stuff.map<double>((n) => n * 2);

非推奨:

// Lazy cast (performance hit on every access)
var stuff = <dynamic>[1, 2];
var ints = stuff.toList().cast<int>();

var reciprocals = stuff.map((n) => n * 2).cast<double>();

ワークフロー:レガシーコレクションのリファクタリング

レガシーな Dart コードを最新の標準に更新する際は、次の順序付きチェックリストに従ってください。

タスクの進捗
  • ステップ 1:コンストラクターを置き換える。 Map()、Set()、および(該当する場合)List() を検索します。<K, V>{}、<T>{}、<T>[] に置き換えます。
  • ステップ 2:.length のチェックをなくす。 .length == 0、.length > 0、.length != 0 を正規表現で検索します。.isEmpty または .isNotEmpty に置き換えます。
  • ステップ 3:命令型の構築を簡潔にする。 新しくインスタンス化したコレクションに対する、連続した .add() および .addAll() の呼び出しを特定します。コレクションリテラル内で ...、if、for を使う形に書き換えます。
  • ステップ 4:.cast<T>() を削除する。 .cast< を検索します。
    • .toList() の後に適用されている場合は、List<T>.from() に置き換えます。
    • .where() の後に適用されている場合は、.whereType<T>() に置き換えます。
    • .map() の後に適用されている場合は、map の呼び出しにジェネリック型を追加します:.map<T>(...)。
  • ステップ 5:バリデーターを実行し、エラーを確認して修正する。 dart analyze を実行して、リファクタリング中に型の昇格や構文のエラーが発生していないことを確認します。

コメント