Effective Dart: スタイル
- 識別子
- 型名にはUpperCamelCaseを使用すること
- 拡張機能名にはUpperCamelCaseを使用すること
- パッケージ、ディレクトリ、およびソースファイルの名前には、lowercase_with_underscoresを使用してください。
- インポートプレフィックスの名前には、lowercase_with_underscoresを使用してください。
- その他の識別子名にはlowerCamelCaseを使用すること
- 定数名にはlowerCamelCaseを使用することが望ましい
- 3文字以上の頭字語や略語は単語のように大文字にすること
- 使用されていないコールバックパラメータには、_、__などを使用することをお勧めします。
- プライベートでない識別子に先頭にアンダースコアを使用しないこと
- 接頭辞を使用しないこと
- ライブラリに明示的に名前を付けないこと
- 順序
- フォーマット
優れたコードの驚くほど重要な部分は、優れたスタイルです。一貫した命名、順序付け、およびフォーマットは、 *同じ* であるコードが *同じように見える* のに役立ちます。これは、私たちのほとんどが眼球系に持っている強力なパターンマッチングハードウェアを利用しています。Dartエコシステム全体で一貫したスタイルを使用すると、全員が互いのコードから学び、貢献しやすくなります。
識別子
#Dartには、3種類の識別子があります。
UpperCamelCase
名は、最初の単語を含む各単語の最初の文字を大文字にします。lowerCamelCase
名は、最初の単語を除く各単語の最初の文字を大文字にします。最初の単語は、頭字語であっても常に小文字です。lowercase_with_underscores
名は、頭字語であっても小文字のみを使用し、単語を_
で区切ります。
型名にはUpperCamelCase
を使用すること
#リンタールール: camel_case_types
クラス、列挙型、型定義、および型パラメータは、各単語(最初の単語を含む)の最初の文字を大文字にし、区切り文字を使用しないでください。
class SliderMenu { ... }
class HttpRequest { ... }
typedef Predicate<T> = bool Function(T value);
これには、メタデータアノテーションで使用することを目的としたクラスも含まれます。
class Foo {
const Foo([Object? arg]);
}
@Foo(anArg)
class A { ... }
@Foo()
class B { ... }
アノテーションクラスのコンストラクタがパラメータを取らない場合は、別のlowerCamelCase
定数を作成することをお勧めします。
const foo = Foo();
@foo
class C { ... }
拡張機能名にはUpperCamelCase
を使用すること
#リンタールール: camel_case_extensions
型と同様に、拡張機能は各単語(最初の単語を含む)の最初の文字を大文字にし、区切り文字を使用しないでください。
extension MyFancyList<T> on List<T> { ... }
extension SmartIterable<T> on Iterable<T> { ... }
パッケージ、ディレクトリ、およびソースファイルの名前には、lowercase_with_underscores
を使用すること
#リンタールール: file_names、package_names
ファイルシステムによっては、大文字と小文字が区別されないため、多くのプロジェクトではファイル名をすべて小文字にする必要があります。区切り文字を使用すると、その形式でも名前を読みやすくすることができます。区切り文字としてアンダースコアを使用すると、名前が有効なDart識別子のままであることが保証されます。これは、言語が後でシンボリックインポートをサポートする場合に役立つ可能性があります。
my_package
└─ lib
└─ file_system.dart
└─ slider_menu.dart
mypackage
└─ lib
└─ file-system.dart
└─ SliderMenu.dart
インポートプレフィックス名にはlowercase_with_underscores
を使用すること
#リンタールール: library_prefixes
import 'dart:math' as math;
import 'package:angular_components/angular_components.dart' as angular_components;
import 'package:js/js.dart' as js;
import 'dart:math' as Math;
import 'package:angular_components/angular_components.dart' as angularComponents;
import 'package:js/js.dart' as JS;
その他の識別子名にはlowerCamelCase
を使用すること
#リンタールール: non_constant_identifier_names
クラスメンバー、トップレベル定義、変数、パラメータ、および名前付きパラメータは、最初の単語 *を除く* 各単語の最初の文字を大文字にし、区切り文字を使用しないでください。
var count = 3;
HttpRequest httpRequest;
void align(bool clearItems) {
// ...
}
定数名にはlowerCamelCase
を使用することが望ましい
#リンタールール: constant_identifier_names
新しいコードでは、列挙値を含む定数変数にlowerCamelCase
を使用してください。
const pi = 3.14;
const defaultTimeout = 1000;
final urlScheme = RegExp('^([a-z]+):');
class Dice {
static final numberGenerator = Random();
}
const PI = 3.14;
const DefaultTimeout = 1000;
final URL_SCHEME = RegExp('^([a-z]+):');
class Dice {
static final NUMBER_GENERATOR = Random();
}
以下の場合のように、既存のコードとの整合性のためにSCREAMING_CAPS
を使用しても構いません。
- すでに
SCREAMING_CAPS
を使用しているファイルまたはライブラリにコードを追加する場合。 - Javaコードと並列のDartコードを生成する場合(たとえば、protobufから生成された列挙型など)。
3文字以上の頭字語や略語は単語のように大文字にすること
#大文字の頭字語は読みにくく、複数の頭字語が隣接していると、あいまいな名前になる可能性があります。たとえば、識別子HTTPSFTP
が与えられた場合、読者はそれがHTTPS
FTP
を指すのか、それともHTTP
SFTP
を指すのかを判断できません。これを避けるために、ほとんどの頭字語と略語は通常の単語のように大文字にします。この識別子は、前者を指す場合はHttpsFtp
、後者を指す場合はHttpSftp
になります。
2文字の略語と頭字語は例外です。英語で両方の文字が大文字になっている場合は、識別子で使用するときも両方を大文字のままにする必要があります。そうでない場合は、単語のように大文字にします。
// Longer than two letters, so always like a word:
Http // "hypertext transfer protocol"
Nasa // "national aeronautics and space administration"
Uri // "uniform resource identifier"
Esq // "esquire"
Ave // "avenue"
// Two letters, capitalized in English, so capitalized in an identifier:
ID // "identifier"
TV // "television"
UI // "user interface"
// Two letters, not capitalized in English, so like a word in an identifier:
Mr // "mister"
St // "street"
Rd // "road"
HTTP // "hypertext transfer protocol"
NASA // "national aeronautics and space administration"
URI // "uniform resource identifier"
esq // "esquire"
Ave // "avenue"
Id // "identifier"
Tv // "television"
Ui // "user interface"
MR // "mister"
ST // "street"
RD // "road"
何らかの形の略語がlowerCamelCase
識別子の先頭にある場合、略語はすべて小文字にする必要があります。
var httpConnection = connect();
var tvSet = Television();
var mrRogers = 'hello, neighbor';
未使用のコールバックパラメータには_
、__
などを使用することが望ましい
#コールバック関数の型シグネチャではパラメータが必要ですが、コールバックの実装ではパラメータを *使用しない* 場合があります。この場合、未使用のパラメータに_
という名前を付けるのが慣用的です。関数に複数の未使用のパラメータがある場合は、名前の衝突を避けるために追加のアンダースコア(__
、___
など)を使用します。
futureOfVoid.then((_) {
print('Operation complete.');
});
このガイドラインは、 *匿名でローカル* の関数のみに適用されます。これらの関数は通常、未使用のパラメータが何を表しているかが明らかなコンテキストですぐに使用されます。対照的に、トップレベル関数とメソッド宣言にはそのコンテキストがないため、使用されていない場合でも、各パラメータが何のためにあるかが明らかになるように、パラメータに名前を付ける必要があります。
プライベートでない識別子に先頭にアンダースコアを使用しないこと
#Dartは、識別子の先頭にアンダースコアを使用して、メンバーとトップレベルの宣言をプライベートとしてマークします。これにより、ユーザーは先頭のアンダースコアをこれらの種類の宣言のいずれかと関連付けるようにトレーニングされます。彼らは「_」を見て「プライベート」と考えます。
ローカル変数、パラメータ、ローカル関数、またはライブラリプレフィックスには、「プライベート」の概念はありません。これらのいずれかの名前がアンダースコアで始まる場合、読者に混乱した信号を送信します。それを避けるために、それらの名前には先頭のアンダースコアを使用しないでください。
接頭辞を使用しないこと
#ハンガリアン記法やその他のスキームは、BCPLの時代に登場しました。その当時は、コンパイラはコードを理解するのにそれほど役立ちませんでした。Dartは、宣言の型、スコープ、変更可能性、およびその他のプロパティを伝えることができるため、これらのプロパティを識別子名にエンコードする理由はありません。
defaultTimeout
kDefaultTimeout
ライブラリに明示的に名前を付けないこと
#library
ディレクティブに名前を追加することは技術的には可能ですが、レガシー機能であり、推奨されません。
Dartは、パスとファイル名に基づいて各ライブラリに一意のタグを生成します。ライブラリに名前を付けると、この生成されたURIがオーバーライドされます。URIがないと、ツールが問題のメインライブラリファイルを見つけるのが難しくなる可能性があります。
library my_library;
/// A really great test library.
@TestOn('browser')
library;
順序
#ファイルのプリアンブルを整理するために、ディレクティブが表示されるべき順序が規定されています。各「セクション」は空白行で区切る必要があります。
すべての順序付けガイドラインは、単一のリンタールール directives_ordering によって処理されます。
**推奨:** dart:
インポートを他のインポートの前に配置します。
#リンタールール: directives_ordering
import 'dart:async';
import 'dart:html';
import 'package:bar/bar.dart';
import 'package:foo/foo.dart';
**推奨:** package:
インポートを相対インポートの前に配置します。
#リンタールール: directives_ordering
import 'package:bar/bar.dart';
import 'package:foo/foo.dart';
import 'util.dart';
すべてのインポートの後、別のセクションにエクスポートを指定すること
#リンタールール: directives_ordering
import 'src/error.dart';
import 'src/foo_bar.dart';
export 'src/error.dart';
import 'src/error.dart';
export 'src/error.dart';
import 'src/foo_bar.dart';
セクションをアルファベット順にソートすること
#リンタールール: directives_ordering
import 'package:bar/bar.dart';
import 'package:foo/foo.dart';
import 'foo.dart';
import 'foo/foo.dart';
import 'package:foo/foo.dart';
import 'package:bar/bar.dart';
import 'foo/foo.dart';
import 'foo.dart';
フォーマット
#多くの言語と同様に、Dartは空白を無視します。しかし、*人間*は無視しません。一貫した空白スタイルを持つことで、人間がコードをコンパイラと同じように見ることができるようになります。
**推奨:** dart format
を使用してコードをフォーマットします。
#フォーマットは面倒な作業であり、特にリファクタリング中は時間がかかります。幸いなことに、それについて心配する必要はありません。Dartには、自動的にコードをフォーマットする洗練された dart format
が用意されています。適用されるルールについてはドキュメントがありますが、Dartの公式の空白処理ルールは、*`dart format` が生成するもの*です。
残りのフォーマットガイドラインは、dart format
が修正できない少数の項目に関するものです。
フォーマッターに優しいコードに変更することを検討すること
#フォーマッターは、どのようなコードに対しても最善を尽くしますが、奇跡を起こすことはできません。コードに特に長い識別子、深くネストされた式、さまざまな種類の演算子が混在している場合など、フォーマットされた出力は依然として読みづらい可能性があります。
そのような場合は、コードを再構成または簡略化します。ローカル変数名を短縮したり、式を新しいローカル変数に抽出することを検討してください。言い換えれば、コードを手動でフォーマットし、より読みやすくしようとする場合と同じ種類の変更を加えます。dart format
は、美しいコードを作成するために、時には反復的に協力するパートナーと考えてください。
80文字を超える行は避けること
#リンタールール: lines_longer_than_80_chars
可読性に関する研究によると、長いテキスト行は、次の行の先頭に移動するときに目が遠くまで移動する必要があるため、読みづらいことがわかっています。これが、新聞や雑誌が複数のテキスト列を使用する理由です。
どうしても80文字より長い行が必要な場合は、経験上、コードが冗長すぎて、もう少しコンパクトにできる可能性があります。主な原因は、通常、VeryLongCamelCaseClassNames
です。その型名の各単語は、重要な情報を伝えているか、名前の衝突を防いでいるか、自問してみてください。そうでない場合は、省略することを検討してください。
dart format
はこの作業の99%を自動的に行いますが、残りの1%は手動で行う必要があります。長い文字列リテラルを80列に収まるように分割することはしないため、手動で行う必要があります。
**例外:** URIまたはファイルパスがコメントまたは文字列(通常はimportまたはexport)に含まれている場合、行が80文字を超えても、そのままにしておくことができます。これにより、ソースファイル内でパスを検索しやすくなります。
**例外:** 複数行の文字列には、80文字を超える行を含めることができます。これは、文字列内では改行が重要であり、行を短い行に分割するとプログラムが変更される可能性があるためです。
すべての制御フロー文に中括弧を使用すること
#リンタールール: curly_braces_in_flow_control_structures
そうすることで、ぶら下がりelse 問題を回避できます。
if (isWeekDay) {
print('Bike to work!');
} else {
print('Go dancing or read a book!');
}
**例外:** else
節のない if
文があり、if
文全体が1行に収まる場合は、必要に応じて中括弧を省略できます。
if (arg == null) return defaultValue;
ただし、本体が次の行に折り返される場合は、中括弧を使用します。
if (overflowChars != other.overflowChars) {
return overflowChars < other.overflowChars;
}
if (overflowChars != other.overflowChars)
return overflowChars < other.overflowChars;
特に明記されていない限り、このサイトのドキュメントはDart 3.5.3を反映しています。ページの最終更新日: 2024-08-04。 ソースを表示 または 問題を報告する.