🐇

Effective Dart: Style

2022/06/09に公開

良いコードで意外と重要なのが、良いスタイルです。一貫性のある名前、順序、書式は、同じコードが同じように見えるようにします。これは、私たちの眼球システムに備わっている強力なパターンマッチングのハードウェアを利用したものです。Dartのエコシステム全体で一貫したスタイルを使えば、私たち全員が他の人のコードから学び、貢献することが容易になります。

How to read the guides
  • DO:常に従うべき慣習を記述したものです。そこから外れる正当な理由は、ほとんどないでしょう。
  • DON'T:その逆で、ほとんど良いアイデアとは言えないものです。願わくば、他の言語に比べて歴史的経緯が浅いため、このようなガイドラインはあまりないことを願います。
  • PREFER:あなたが従うべき慣習です。しかし、そうでなくても意味のある状況があるかもしれません。ただし、ガイドラインを無視した場合の影響を十分に理解しておく必要があります。
  • AVOID:「好ましい」の対極にあるもので、やってはいけないが、まれにやってもよい理由があるものです。
  • CONSIDER:状況や前例、自分の好みによって、従ったほうがいい場合とそうでない場合があるガイドラインです。

Identifiers

Dartでは、識別子に3つの種類があります。

  • upperCamelCase名前では、各単語の最初の文字が大文字になり、最初の文字も含まれます。
  • lowerCamelCase名前では、頭文字を除き、各単語の最初の文字を大文字にします。
  • lowercase_with_underscores 頭文字であっても、小文字のみを使用し、単語は _ で区切ります。

DO name types using UpperCamelCase.

クラス、enum型、typedef、型パラメータは、各単語の最初の文字を大文字にし(最初の単語を含む)、セパレータを使用しないでください。

good
class SliderMenu { ... }

class HttpRequest { ... }

typedef Predicate<T> = bool Function(T value);

これには、メタデータ注釈で使用されることを意図したクラスも含まれます。

good
class Foo {
  const Foo([Object? arg]);
}

(anArg)
class A { ... }

()
class B { ... }

アノテーションクラスのコンストラクタがパラメータを取らない場合、それ用に別のlowerCamelCase定数を作成したほうがよいかもしれません。

good
const foo = Foo();


class C { ... }

DO name extensions using UpperCamelCase.

タイプ同様、拡張子は各単語の最初の文字を大文字にし(最初の単語を含む)、セパレータを使用しない。

good
extension MyFancyList<T> on List<T> { ... }

extension SmartIterable<T> on Iterable<T> { ... }

DO name libraries, packages, directories, and source files using lowercase_with_underscores.

ファイルシステムによっては大文字と小文字が区別されないため、多くのプロジェクトではファイル名をすべて小文字にする必要があります。区切り文字を使用することで、そのような形式でも名前を読むことができます。アンダースコアをセパレータとして使用すると、名前が有効な Dart 識別子であることが保証されます。これは、言語が後にシンボリックインポートをサポートする場合に便利です。

good
library peg_parser.source_scanner;

import 'file_system.dart';
import 'slider_menu.dart';
bad
library pegparser.SourceScanner;

import 'file-system.dart';
import 'SliderMenu.dart';

DO name import prefixes using lowercase_with_underscores.

good
import 'dart:math' as math;
import 'package:angular_components/angular_components.dart' as angular_components;
import 'package:js/js.dart' as js;
bad
import 'dart:math' as Math;
import 'package:angular_components/angular_components.dart' as angularComponents;
import 'package:js/js.dart' as JS;

DO name other identifiers using lowerCamelCase.

クラスメンバー、トップレベル定義、変数、パラメータ、名前付きパラメータは、最初の単語を除く各単語の最初の文字を大文字にし、セパレータを使用しないでください。

good
var count = 3;

HttpRequest httpRequest;

void align(bool clearItems) {
  // ...
}

PREFER using lowerCamelCase for constant names.

新しいコードでは、enum 値を含む定数変数に lowerCamelCase を使用します。

good
const pi = 3.14;
const defaultTimeout = 1000;
final urlScheme = RegExp('^([a-z]+):');

class Dice {
  static final numberGenerator = Random();
}
bad
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コードを生成する場合-例えば、protobufsから生成される列挙型において。

DO capitalize acronyms and abbreviations longer than two letters like words.

大文字の頭字語は読みにくく、また、複数の頭字語が隣接していると、曖昧な名前になる可能性があります。例えば、HTTPSFTPで始まる名前があった場合、それがHTTPS FTPを指しているのか、HTTP SFTPを指しているのかを見分ける方法はありません。

これを避けるため、頭字語や略語は、通常の単語と同様に大文字で表記します。

例外: IO (input/output) のような2文字の頭字語は、完全に大文字にします。IO。一方、ID(identification)のような2文字の略語は、やはり通常の単語と同じように大文字で表記されます。

good
class HttpConnection {}
class DBIOPort {}
class TVVcr {}
class MrRogers {}

var httpRequest = ...
var uiHandler = ...
var userId = ...
Id id;
bad
class HTTPConnection {}
class DbIoPort {}
class TvVcr {}
class MRRogers {}

var hTTPRequest = ...
var uIHandler = ...
var userID = ...
ID iD;

PREFER using _, __, etc. for unused callback parameters.

コールバック関数の型名にはパラメータが必要ですが、コールバックの実装ではそのパラメータを使用しない場合があります。このような場合、未使用のパラメータに _ という名前を付けるのが一般的です。関数に複数の未使用のパラメータがある場合は、名前の衝突を避けるために追加のアンダースコアを使用します。や ___ などです。

good
futureOfVoid.then((_) {
  print('Operation complete.');
});

このガイドラインは、匿名かつローカルな関数のみを対象としています。これらの関数は、通常、未使用のパラメータが何を表しているかが明らかな状況ですぐに使用されます。一方、トップレベル関数やメソッド宣言にはそのような文脈がないため、たとえ使用されない場合でも、それぞれのパラメータが何のためにあるのかが明確になるような名前を付けなければなりません。

DON’T use a leading underscore for identifiers that aren’t private.

Dart では、識別子の先頭のアンダースコアを使用してメンバーやトップレベルの宣言をプライベートなものとしてマークします。これにより、ユーザは先頭のアンダースコアをこれらの宣言のいずれかに関連付けるようになります。ユーザは "_" を見て "private" と思うのです。

ローカル変数、パラメータ、ローカル関数、ライブラリの接頭辞には「プライベート」という概念はありません。アンダースコアで始まる名前があると、読者は混乱します。それを避けるために、これらの名前に先頭のアンダースコアを使わないようにしましょう。

DON’T use prefix letters.

ハンガリー記法やその他の方式は、コンパイラがコードを理解するのにあまり役立たなかった BCPLの時代に生まれました。Dartは宣言の型、スコープ、ミュータビリティ、その他のプロパティを教えてくれるので、それらのプロパティを識別子名でエンコードする理由はないのです。

good
defaultTimeout
bad
kDefaultTimeout

Discussion