Effective Dart
過去数年間、私たちは大量のDartコードを書き、何がうまく機能し、何がうまくいかなかったかについて多くのことを学びました。そのため、皆さんも一貫性があり、堅牢で、高速なコードを書くことができるように、この知識を共有しています。2つの包括的なテーマがあります。
- 一貫性を保つこと。 フォーマットやキャスティングなどのことに関しては、どちらが良いかという議論は主観的であり、解決することは不可能です。私たちが知っているのは、一貫性があることが客観的に役立つということです。 - 2つのコード片が異なって見える場合、それはそれらが意味のある方法で異なっているためであるべきです。コードの一部が際立って目に留まる場合は、それは有用な理由があるからであるべきです。 
- 簡潔にすること。 Dartは馴染みやすいように設計されており、C、Java、JavaScriptなどの多くの言語と同じステートメントや式を継承しています。しかし、私たちはDartを、これらの言語が提供するものには改善の余地がたくさんあるという理由で作成しました。文字列補間から初期化フォーマルまで、意図をよりシンプルかつ容易に表現するのに役立つ多くの機能を追加しました。 - 何かを表現する方法が複数ある場合は、一般的に最も簡潔な方法を選ぶべきです。これは、プログラム全体を1行に詰め込むためにコードゴルフをするべきだという意味ではありません。目標は、密度の高いコードではなく、経済的なコードです。 
ガイド
#理解を容易にするために、ガイドをいくつかの別々のページに分割しました。
- スタイルガイド – これは、コードのレイアウトと整理のルールを定義します。少なくとも、 - dart formatが処理しない部分です。スタイルガイドは、識別子のフォーマット方法も指定します。- camelCase、- using_underscoresなど。
- ドキュメントガイド – これは、コメントに何を含めるべきかについてのすべての情報を提供します。ドキュメントコメントと通常の、ありふれたコードコメントの両方です。 
- 使用ガイド – これは、言語機能を使用して動作を実装する最良の方法を教えます。ステートメントまたは式にあるものはすべて、ここでカバーされます。 
- デザインガイド – これは最も緩やかなガイドですが、最も広範囲に及びます。ライブラリ向けの、一貫性があり使いやすいAPIを設計することについて学んだことをカバーしています。型シグネチャまたは宣言にあるものはすべて、ここで説明されます。 
すべてのガイドへのリンクについては、概要を参照してください。
ガイドの読み方
#各ガイドはいくつかのセクションに分かれています。セクションにはガイドのリストが含まれています。各ガイドはこれらの単語のいずれかで始まります。
- DO ガイドは、常に従うべきプラクティスを説明します。それに従わない正当な理由はほとんどないでしょう。 
- DON'T ガイドは、その逆です。ほとんど常に良い考えではないことです。幸いなことに、他の言語よりもこれらの数が少ないはずです。なぜなら、歴史的な負債が少ないからです。 
- PREFER ガイドは、従うべきプラクティスです。ただし、そうしないことが理にかなる状況があるかもしれません。無視するときは、その含意を完全に理解していることを確認してください。 
- AVOID ガイドは、「prefer」の二重です。従うべきではないが、まれに良い理由があるかもしれないものです。 
- CONSIDER ガイドは、状況、先例、および自身の好みに応じて、従うべき場合も従わない場合もあるプラクティスです。 
一部のガイドでは、ルールが適用されない例外を説明しています。リストされている場合、例外は網羅的ではないかもしれません。他のケースでも、判断力が必要になる場合があります。
これは、靴ひもを正しく結ばないと警察がドアを叩き壊しに来るようなものに聞こえるかもしれません。それほどひどいものではありません。ここのガイドのほとんどは常識であり、私たちは皆合理的な人々です。いつものように、目標は、きれいで、読みやすく、保守しやすいコードです。
Dartアナライザーは、これらのガイドラインやその他のガイドラインに従った、良好で一貫性のあるコードを作成するのに役立つリンターを提供します。ガイドラインに従うのに役立つリンター ルールが1つ以上存在する場合、ガイドラインはそのルールにリンクします。リンクは次の形式を使用します。
リンター ルール: unnecessary_getters_setters
リンターの使用方法については、リンター ルールの有効化とリンター ルールのリストを参照してください。
用語集
#ガイドを簡潔にするために、さまざまなDart構造を参照するためにいくつかの略語を使用します。
- ライブラリメンバーは、トップレベルのフィールド、ゲッター、セッター、または関数です。基本的に、型ではないトップレベルのものはすべてです。 
- クラスメンバーは、クラス内で宣言されたコンストラクタ、フィールド、ゲッター、セッター、関数、または演算子です。クラスメンバーは、インスタンスまたは静的、抽象または具象にすることができます。 
- メンバーは、ライブラリメンバーまたはクラスメンバーのいずれかです。 
- 変数は、一般的に使用される場合、トップレベル変数、パラメータ、およびローカル変数を指します。静的フィールドまたはインスタンスフィールドは含まれません。 
- 型は、名前付き型宣言(クラス、typedef、またはenum)です。 
- プロパティは、トップレベル変数、ゲッター(クラス内またはトップレベル、インスタンスまたは静的)、セッター(同上)、またはフィールド(インスタンスまたは静的)です。ほぼすべての「フィールドのような」名前付き構造です。 
すべてのルールの概要
#スタイル
#識別子
- 型にはUpperCamelCaseを使用してください。
- 拡張機能にはUpperCamelCaseを使用してください。
- パッケージ、ディレクトリ、ソースファイルにはlowercase_with_underscoresを使用してください。
- インポートプレフィックスにはlowercase_with_underscoresを使用してください。
- その他の識別子にはlowerCamelCaseを使用してください。
- 定数名にはlowerCamelCaseを使用することを推奨します。
- 2文字より長い頭字語や略語は、単語のように大文字にしてください。
- 未使用のコールバックパラメータにはワイルドカードを使用することを推奨します。
- プライベートではない識別子に先頭アンダースコアを使用しないでください。
- プレフィックス文字を使用しないでください。
- ライブラリを明示的に名前付けしないでください。
順序
- dart:インポートは、他のインポートの前に配置してください。
- package:インポートは、相対インポートの前に配置してください。
- エクスポートは、すべてのインポートの後の別のセクションに指定してください。
- セクションはアルファベット順に並べてください。
フォーマット
ドキュメント
#コメント
ドキュメントコメント
- メンバーと型をドキュメント化するには、///ドキュメントコメントを使用してください。
- 公開APIにはドキュメントコメントを作成することを推奨します。
- ライブラリレベルのドキュメントコメントを作成することを検討してください。
- プライベートAPIにはドキュメントコメントを作成することを検討してください。
- ドキュメントコメントは、1文の概要で始めてください。
- ドキュメントコメントの最初の文は、独自の段落に分離してください。
- 周囲のコンテキストとの冗長性を避けてください。
- 関数またはメソッドのコメントは、その主な目的が副作用である場合、三人称動詞で始めることを推奨します。
- ブール値でない変数またはプロパティのコメントは、名詞句で始めることを推奨します。
- ブール値の変数またはプロパティのコメントは、「〜かどうか」に続けて名詞または動名詞句で始めることを推奨します。
- 値の返還が主な目的である関数またはメソッドのコメントは、名詞句または非命令動詞句を推奨します。
- プロパティのゲッターとセッターの両方にドキュメントを作成しないでください。
- ライブラリまたは型のコメントは、名詞句で始めることを推奨します。
- ドキュメントコメントにコードサンプルを含めることを検討してください。
- スコープ内の識別子を参照するには、ドキュメントコメントで角括弧を使用してください。
- パラメータ、戻り値、例外を説明するために、文章を使用してください。
- ドキュメントコメントは、メタデータアノテーションの前に配置してください。
Markdown
執筆
使用法
#ライブラリ
- part ofディレクティブでは文字列を使用してください。
- 他のパッケージのsrcディレクトリ内にあるライブラリをインポートしないでください。
- インポートパスがlibの内外に到達しないようにしてください。
- 相対インポートパスを推奨します。
Null
- 変数に明示的にnullを初期化しないでください。
- 明示的なデフォルト値としてnullを使用しないでください。
- 等価演算でtrueまたはfalseを使用しないでください。
- 初期化されているかどうかを確認する必要がある場合は、late変数を避けてください。
- nullable型を使用するために、型昇格またはnullチェックパターンを検討してください。
文字列
コレクション
- 可能な場合は、コレクションリテラルを使用してください。
- コレクションが空かどうかを確認するために.lengthを使用しないでください。
- 関数リテラルでIterable.forEach()を使用しないでください。
- 結果の型を変更したい場合を除き、List.from()を使用しないでください。
- 型でコレクションをフィルタリングするには、whereType()を使用してください。
- 近くの操作でできる場合は、cast()を使用しないでください。
- cast()の使用を避けてください。
関数
変数
メンバー
- フィールドを不必要にゲッターとセッターでラップしないでください。
- 読み取り専用プロパティにするために、finalフィールドを使用することを推奨します。
- 単純なメンバーには=>の使用を検討してください。
- 名前付きコンストラクタにリダイレクトする場合やシャドウイングを回避する場合を除き、this.を使用しないでください。
- 可能な場合は、宣言時にフィールドを初期化してください。
コンストラクタ
- 可能な場合は、初期化フォーマルを使用してください。
- コンストラクタの初期化子リストで済む場合は、lateを使用しないでください。
- 空のコンストラクタ本文には、{}の代わりに;を使用してください。
- newを使用しないでください。
- 冗長にconstを使用しないでください。
エラー処理
- on句のないcatchを避けてください。
- on句のないcatchからのエラーを破棄しないでください。
- プログラムエラーに対してのみ、Errorを実装するオブジェクトをスローしてください。
- Errorまたはそれを実装する型を明示的にキャッチしないでください。
- キャッチした例外を再スローするには、rethrowを使用してください。
非同期
設計
#名前
- 用語を一貫して使用してください。
- 略語を避けてください。
- 最も説明的な名詞を最後に置くことを推奨します。
- コードが文章のように読めるようにすることを検討してください。
- ブール値でないプロパティまたは変数には名詞句を推奨します。
- ブール値のプロパティまたは変数には、非命令動詞句を推奨します。
- 名前付きブールパラメータの場合は、動詞を省略することを検討してください。
- ブール値のプロパティまたは変数には、「ポジティブ」な名前を推奨します。
- 副作用が主な目的である関数またはメソッドには、命令動詞句を推奨します。
- 値の返還が主な目的である関数またはメソッドのコメントは、名詞句または非命令動詞句を推奨します。
- 実行する作業に注目したい場合は、関数またはメソッドの命令動詞句を検討してください。
- メソッド名をgetで始めないでください。
- オブジェクトの状態を新しいオブジェクトにコピーするメソッドは、to___()と名付けることを推奨します。
- 元のオブジェクトでバックアップされた異なる表現を返すメソッドは、as___()と名付けることを推奨します。
- 関数またはメソッドの名前でパラメータを説明することを避けてください。
- 型パラメータの名前付けでは、既存のニーモニック規約に従ってください。
ライブラリ
クラスとミックスイン
- 1メンバーの抽象クラスを、単純な関数で済む場合に定義しないでください。
- 静的メンバーのみを含むクラスを定義しないでください。
- サブクラス化を意図されていないクラスを継承しないでください。
- クラスを拡張できるかどうかを制御するには、クラス修飾子を使用してください。
- インターフェースとして意図されていないクラスを実装しないでください。
- クラスがインターフェースとして機能できるかどうかを制御するには、クラス修飾子を使用してください。
- 純粋なmixinまたは純粋なclassをmixin classよりも定義することを推奨します。
コンストラクタ
メンバー
- フィールドとトップレベル変数をfinalにすることを推奨します。
- 概念的にプロパティにアクセスする操作には、ゲッターを使用してください。
- 概念的にプロパティを変更する操作には、セッターを使用してください。
- 対応するゲッターなしでセッターを定義しないでください。
- オーバーロードを偽装するために、実行時型テストを使用しないでください。
- 初期化子なしのパブリックlate finalフィールドを避けてください。
- nullableなFuture、Stream、およびコレクション型を返さないでください。
- 流暢なインターフェースを有効にするためだけに、メソッドからthisを返さないでください。
型
- 初期化子がない変数には、型注釈を付けてください。
- 型が明白でない場合は、フィールドとトップレベル変数に型注釈を付けてください。
- 初期化されたローカル変数に冗長な型注釈を付けないでください。
- 関数宣言に、戻り値の型を注釈付けしてください。
- 関数宣言に、パラメータの型を注釈付けしてください。
- 関数式に、推論されるパラメータ型を注釈付けしないでください。
- 初期化フォーマルに型注釈を付けないでください。
- 推論されないジェネリック呼び出しに型引数を記述してください。
- 推論されるジェネリック呼び出しに型引数を記述しないでください。
- 不完全なジェネリック型を記述することを避けてください。
- 推論が失敗した場合に備えて、dynamicで注釈を付けてください。
- 関数型注釈ではシグネチャを推奨します。
- セッターの戻り値の型を指定しないでください。
- レガシーtypedef構文を使用しないでください。
- typedefよりもインライン関数型を推奨します。
- パラメータには関数型構文を使用することを推奨します。
- 静的チェックを無効にしたい場合を除き、dynamicを使用しないでください。
- 値を作成しない非同期メンバーの戻り値の型としてFuture<void>を使用してください。
- 戻り値の型としてFutureOr<T>を使用しないでください。
パラメータ
- 位置指定ブールパラメータを避けてください。
- ユーザーが前のパラメータを省略したい場合がある場合は、オプショナルな位置指定パラメータを避けてください。
- 「引数なし」の特別な値を受け入れる必須パラメータを避けてください。
- 範囲を指定するには、包括的な開始パラメータと排他的な終了パラメータを使用してください。
等価性