言語編 |
*** Dart 2 の解説:言語編 ***
従来の「プログラミング言語Dartの基礎」では言語仕様書に準拠して解説していたが、Dart 2の言語仕様書は現在全く別のメンバーで作成中(現在の状況はDart Language Specificationを参照されたい)なので、ここでは言語概説書(A Tour of the Dart Language)の和訳をベースとし、一部を補足して解説する。より詳細はEffective DartやA Tour of the Dart Librariesなどが参考になる。
注意:この解説書の中のサンプル・コードの多くはDartPadを使って読者が確認できる。DartPadはこれまでのDartiumに変わるオンラインの開発ツールで、組み込みのライブラリしか使用できないものの他のユーザとの共有が可能など多くの特徴を持っている。DartPadに関しては開発編の「DartPad」でより詳しく解説してある。
Dartは大規模(Googleのアプリ規模)で構造化されたウェブ・アプリーケーション(サーバ・サイドとクライアント・サイドの双方において)に対応可能なプログラミング言語である。Dartの開発の中心になったのがChromeブラウザのV8エンジンを担当したLars Bak(ラース・バーク)などであり、従ってDartはJavaScriptのV8エンジンの経験がベースになっている。またLars Bak, Kasper Lund, Gilad Bracha, Eric Claybergを含むDart言語の開発チームの多くはSmalltalkの開発に関わってきた経験を持っていることもDartを馴染み安い言語としている。Lars BakとJava言語仕様の作成者の一人であるGilad Bracha(ジラード・ブラーカ)が2011年10月にこの言語を最初に公式に発表したときのプレゼンテーションでは、この言語のことを「シンプルで意外性のないオブジェクト指向プログラミング言語」(A simple and unsurprising OO programming language)だと述べている。即ち:
Dartでは総てがオブジェクトである(Javaのプリミティブのようなものは存在しない)
クラス・ベース、単一継承、インターフェイスつき
静的な型づけはオプショナル
真の構文スコープ
単一スレッド。並行処理はアイソレートで実現可能
なじみのある文法
が特徴だとしている。
シンプル性の追求はGoogle社の社風であり、これは言語及びAPIの仕様からも良く窺われる。DartはJavaに比べるとずっと簡潔(succinct)である。シンプルな言語にすることは次のような利点をもたらすとLars BakがこのチームのKasper Lundがともに行ったGoogle I/O 2013でのプレゼンテーションで述べている:
高速化が可能
生成されるコードが小さくなる
性能の予測可能性が高まる
Dart言語はECMAで標準化が行われ、2014年6月末に承認された。但しDart 2の標準化は進行中である。
筆者は株式会社クレスのサイトのなかでその初期時点から「プログラミング言語Dartの基礎」としてDart言語の最新の内容を紹介し続け、2016年末で36版にまでなった。Dartはその後多くの発展過程を経て、現在はDart 2としてモバイルを含む新しい環境に適応している。
以下にその推移を紹介する:
Dartの仕様書は頻繁に更新されていたなか、Dartチームは何時1.0版としてリリースするかを発表することを拒んできていた。彼らはDartをより革新的で魅力的なものとすることに専念していた。しかしながら2012年10月16日にDartチームが最初の安定版が出たと発表したと報じられた。これはM1版のことを意味し、この発表は、10月1日のMicrosoftからのTypeScript発表に対抗する意味もあろう。
2013年11月14日に仕様書がついにM版から1.0版に改版された。またSDKもDart SDK version 1.0.0.3_r3018となった。Dartチームはこれに関し正式な発表をしたが、これは11月11-15日にベルギーで開催されたDevoxx Conferenceに合わせたもので、シンボリックなものでしかない。2.0版まではもう大きな変更を加えないという意味だったらしい。
11月18日開催されたLars Bakが主催するこのチームの中心人物たちによる毎週の会合(Language Meeting)では次のような議論がなされている:
自分たちは今後の変更に対してはより慎重にならねばならないこと。
さらなる機能追加項目の多くについてはECMAでの標準化の作業の中で進めることになる。
それまでは安定化に集中する。
2014年1月16日に安定版1.1が発表されている。高速化がはかられ1.0版に比べてRichards benchmarkで25%改善されている。サーバ・サイド(dart:io)では大サイズのファイル対応、ファイル・コピー、プロセス・シグナル・ハンドラ、および端末情報などに対応している。またストリーミング用にUDPプロトコルも扱えるようになった。
その後の改版はDartのSDKのCHANGELOG.MDを見て頂きたい。2017年12月24日の1.24.3版までの詳細が記されている。これらの改版は新たなアプリケーション環境の発展に対応するもので、これまでの技術者たちの多くはこのチームを離れ、新しいメンバーでの作業が進められた。
2018年2月に、当初からのこの言語の開発に携わっていたAnders Thorhauge SandholmがDart 2を発表した。Dart 2はよりクライアント・サイドの開発に重点が置かれてはいるが、サーバ・サイドでもこれまでどおり活用可能である。Dart 2はモバイル環境の発展やAngularなどのウェブ・アプリケーションのフレームワークの普及など、Dart発表当初から大きく変化した環境に対応させるべく進化したものである。
従って開発環境は目的によって最適化されている:
|
環境 |
ツール |
|
iOS 及び Androidなどのモバイル環境 |
Flutter AndroidやiOS向けのDartベースのアプリケーションの開発のフレームワークで、Android上のJavaコードとiOS上のObjectCとSwiftを統合できる |
|
PCなどのクライアント環境 |
AngularDart HTMLとDartを使ってクライアント・アプリケーションを構築するためのオープンソースのJavaScriptフレームワーク |
|
サーバ環境 |
スタンド・アロンVM等 PCのOS上でコマンド行ベースでDartのコードをVM上で実行させる。DartのSDKのみで開発できる |
現時点ではDart 2言語仕様書はボランティア・ベースで標準化作業中である(当初の担当者のGilad Brachaは既にGoogleを去っている)が、まもなくECMAで標準化がされよう。
DartはGoogle内ではGoogle AdWordsが積極的にこれを採用しており、Dart 2はこのチームからのフィードバック等により進化を続けている。Dartのユーザたちの一覧はこのページを参照されたい。
動的型づけに宣言時にオプショナルなintだとかStringだとかの型アノテーションを使う静的型づけを付加した言語は初めてである。これに触発されてMicrosoftはDartの発表からちょうど1年後の2012年10月にMicrosoftの技術フェローのAnders Hejlsbergが「アプリケーション規模のJavaScript開発のための言語」というタイトルでTypeScriptを発表した。これはDartとは違ってJavaScriptの型づけスーパーセットという位置づけである。
Dartのチームは静的な型づけを少し付加しているが動的型付けの利点をプログラマが十分活用できるという目標は崩していないという。ユーザが静的型づけを使うことで:
作られたコードが理解しやすくなる
IDE(統合開発環境)などのツールがそれを使って便利な機能を提供できる
静的チェッカ(static checker)が警告を出し、開発時には実行を止める
dart2jsクロス・コンパイラ(DartコードからJavaScriptコードへの変換)が静的型づけを使って性能をあげることができる
といった、より高度のアプリケーション作成の為のメリットが生じると主張している。
実行時におけるDartの型チェックに対する取り扱いはDart 2からは大きく進化している。強力な型推論(type inference)を採用したいわゆるStrong Modeが導入され、従来のオプショナルな不完全(unsound)な型チェックは廃止された。これは実行時においても実行される。従ってこれまでの実行時におけるchecked mode:チェックド・モード(開発時に使う)とproduction mode:運用モード(運用時に使う)という区分はなくなっている。Strong ModeはDart 2の公式な型システムである。
「重要なコンセプト」の節で示されているように、Dartは強い型付けの言語ではあるが、Dartは型推論ができるので、型アノテーションはオプショナルとなっている。
DartはJavaのように他の言語でも使えるバイト・コード仮想マシン(bytecode VM)の為の中間コードを生成しそれをインタープリタが実行するということはしない。プログラマが書いたコードはそのまま(一旦中間表現に変換されるものの)Dartに特化した言語仮想マシン(language VM)により、その都度コンパイルされ実行される。Dartのチームの説明によれば、VMをDartに特化させることで高い性能を得ることができる。また中間コードを持たないことでセキュリティが上がる。
Dartのコードは次のような構成になる:
|
プログラムはあるライブラリ単位で管理される。ライブラリはトップ・レベルの定数、変数、関数、クラス、インターフェイスなどのコレクションである。他のライブラリの要素をアクセスしたいときはそのライブラリをインポートする。
dart:で指定してインポートするライブラリはDartで用意されDartのSDKに組み込まれている基本ライブラリである。Dartには有用なAPIがdart:core、dart:html、あるいはdart:ioといった多くのライブラリとして用意されている。既に組み込まれているコア・ライブラリ(dart:core)はインポートの必要は無い。
package:で指定してインポートするライブラリたちは開発者たちが共有して登録及び利用できる大規模なもので、pubパッケージマネージャの管理対象となる。
自分のアプリケーションのパッケージ内で留まるライブラリは単純なimport文でインポートできる。例えばa1というディレクトリ内のa1.dartというプログラムがa2というディレクトリ内のa2.dartというライブラリをインポートするにはimport 'a3/a3.dart';と記述すればよい。
ライブラリはまたカプセル化の単位であり、プライバシはライブラリ単位で守られる。Dartのプライベートな要素はその識別子の頭にアンダー・スコア('_')を付す。そのような要素はそのライブラリの中でのみ可視となる。
識別子(identifier)は英数文字(大文字と小文字は識別される)およびアンダスコア('_')を使用する。その他の文字は使用してはいけない。より厳格に説明すれば:
識別子は英数文字が使えるが数字の文字は最初に来てはいけない。
識別子にはアンダスコア(_)またはドル($)を除く特別なシンボルは使えない
識別子はキーワードであってはならない
識別子はユニークであること(同じ名前がそのスコープ内に合ってはいけない)
識別子はスペースを含められない
Dartでは変数、関数、及び型のためには単一の名前空間が使われていることに注意のこと。セッタ/ゲッタ以外で同じスコープ内に同じ名前のものが宣言されているとコンパイル時エラーとなる。
libraryはライブラリを定義し、指定したURIがアクセス可能であればそこに置く。importはURIで指定した他のライブラリをアクセス可能にする(その要素を現在のスコープ内に置く)。
例えば:
|
プレフィックスを付けることで、名前空間がライブラリの中で完結していることによる名前の衝突を解決できる。
ライブラリのトップ・レベルに置かれるのはクラスに含まれない定数宣言、変数宣言、関数宣言、クラス定義、インターフェイス定義などである。これらはこのライブラリ内のどこからでもアクセス可能である。例えばそこに含まれているクラスのオブジェクト内からもアクセスできる。Dartのコア・ライブラリdart:coreには3つのトップ・レベル関数であるvoid print(Object obj)、bool identical(Object a, Object b)およびint identityHashCode(Object object)が存在している。従ってこれらの関数はどこからでも可視である。
トップ・レベル関数であるmain()はDartがこのコードを実行の際引数なし(またはコマンド行引数つき)で呼び出すものであり、これがないと実行時エラーになる。
具体的な例(初期のDartチームの解説書にあったもので、Time: 2019-01-15 19:25:11.441などと現時刻をコンソールに出力する)を示す:
|
このコードの詳細は説明を省くが(この概説書をひととおり読んでから見直して頂きたい)、次のような構成になっている:
このプログラムのトップ・レベルにはcという定数、vという変数、fという関数、Cというクラスがある。
Cというクラスにはmというメソッドのみがある。このメソッドはcとvから作った文字列を返す。
main()の中では次の操作が行われている:
C型のインスタンスmyCを生成する。
変数vにDateTime型の現在の時間を代入する。
myCオブジェクトのm()で取得したString型の値を引数にして関数fを呼ぶ。
トップ・レベルにあるc、v、fは関数main()とクラスCから可視である。
Dartがいう関数とは関数宣言に加えてクラス内のメソッド、セッタ、ゲッタ、コンストラクタ、あるいは関数リテラルをいう。トップ・レベルで宣言されている関数はそのライブラリのどこからも可視であり、これをライブラリ関数とも呼ぶ。メソッドは関数と同じ形式ではあるがクラス定義内で定義されているものをいう。
以下本解説書の内容を理解するために、以下の事項及びコンセプトを念頭に置いておいて頂きたい:
ある変数の中に置けるものの総てはオブジェクトで、各オブジェクトはあるクラスのインスタンスである。数値、関数、そしてnullもオブジェクトである。総てのオブジェクトはObjectクラスから継承している。
Dartは強力な型付け言語ではあるが、Dartは型推論ができるので、型アノテーションはオプショナルとなっている。例えばvar
number =
42;
と変数numberを定義したときは、numberはint型であることが推論される。もしその変数にたいしある特定の型を期待していないと明示的に言いたいときは、特別の型であるdynemicをアノテーションとして付す。
DartはList<int>(整数のリスト)あるいはList<dynamic>(任意の型のリスト)といった総称型に対応している。
Dartはあるクラスまたはオブジェクトに結び付けられた関数(staticメソッドとインスタンス・メソッド)とともに、また関数内に関数(ネストしたあるいはローカルな関数)を作ることも可能である。
同様に、Dartはあるクラスまたはオブジェクトに結び付けられた変数(static変数とインスタンス変数)とともに、トップ・レベルの変数に対応している。インスタンス変数はフィールドまたはプロパティとして知られるものである。
Javaと異なって、Dartにはpublic, protected,及びprivateというキーワードは存在しない。ある識別子の先頭の文字がアンダスコア(_)であるときは、それはそのライブラリのなかでプライベートであることを意味する。
識別子は文字またはアンダスコアで(_)始まり、それ以降はこれらの文字に加えて数字の任意の組み合わせで構成される。
Dartでは式(実行時値を有する)と文(実行時値を有さない)がある。例えば条件式condition
? expr1 : expr2
は
expr1またはexpr2という値を持つ。これに比し
if-else文では値を有さない。文はしばしばひとつまたはそれ以上の式を含むが、式は直接文を含むことはできない。
Dartのツールたちは警告(warnings)とエラー(errors)出すことができる。警告はそのコードは動かないかも知れないがそのプログラムの実行を阻止しないことを単に示している。エラーはそのコードはコンパイル時または実行時で発生しうる。コンパイル時エラーはまったく実行できないが、実行時エラーはそのコードの実行中に例外を生起させる。
なお可視性に関して付記すると、Dartの特徴のひとつに挙げられている「真の静的スコープ(true lexical scoping)」とは、Javaと同じように各識別子がそれが宣言されたブロック内で静的にスコープ付けされているという意味である。すなわち、波括弧で括られたブロック{...}を見ればその変数のスコープを知ることができる。トップ・レベルの変数は従って何処からでも可視である。
例えば次のコードを考えてみよう:
|
の例ではトップ・レベルとif文の中の2か所でfooという変数が定義されている。従ってmainメソッドでこれを実行すると
|
と出力されることになる。
Dartが真の静的スコープだという例として、繰り返しループの中で定義される変数が各繰り返しの中で、その都度きちんとそのループ変数に対応したオブジェクトが生成されるということがある。以下は関数が要素であるfunctionsという配列の例である:
|
ここではfunctions[0]には(){return 0}という関数がセットされる。ループ変数のiはそのループの外部からは不可視である。
一方JavaScriptの場合は:
var functions = []; for (var i = 0; i < 3; i++) { functions[i] = function() { return i }; } functions.forEach(function (fn) { console.log(fn())}); |
functions[0]にはfunction () {return i}という関数がセットされる。従ってその結果はi=3(可視)なので
3
3
|
と表示されてしまう。
Dartではクラスとインターフェイスが分離しておらず、基本的にはクラス・ベースである。クラスを宣言することは暗示的なインターフェイスを宣言することにもなる。クラスたちをextends、 implements及びwithキーワードを使って継承あるいは実装して構成することもできる。
下表はこれらをまとめたものである:
|
クラス |
インターフェイス |
抽象クラス |
ミクスイン (M3から実装された) |
宣言 |
class Javaと同じ |
class 暗示的インターフェイス:あるクラスを定義すると暗示的にインターフェイスももたらされる |
abstract class
|
class 暗示的に定義される |
メンバ |
未実装(即ち抽象メソッド)も許される |
各メソッドは実装されていてもいなくても良い |
少なくともひとつの未実装(抽象)メソッドを持つ |
通常各メソッドは総て実装されている |
使用時のキーワード |
extends(継承するクラスの未実装メンバの総てを実装のこと) new(直接インスタンス化、Dart 2では省略可となった) |
implements |
implements(実装する抽象クラスのメンバの総てを実装のこと) extends(継承する抽象クラスの未実装メソッドを実装のこと) |
with |
注意 |
|
|
|
|
DartのコアAPIライブラリ(即ちdart:core)は基本的な組込みAPIが集められているので、ひととおり知っておく必要があろう。DartではObjectクラスの説明に書かれているように、関数、変数など総てのものがオブジェクトとして扱われている。これはJavaのようにプリミティブな型を持っている言語とは異なる。このObjectがDartのクラス階層のルートとなっている。Objectは識別のためのハッシュコードと実行時の型を取得するruntymeTypeという属性を持っており、またtoString、型が同じかを調べるidentical、及びこのオブジェクトにそのようなメソッドが無いときの為のnoSuchMethodのメソッドが総てのオブジェクトに対し適用できる。本資料はAPIの詳細は扱わないが、最も良く使われる幾つかのクラス及び抽象クラスがどのような構成になっているかを下図に示す。
主要クラスたちの構成 |
|
以下は現時点でGoogleが用意しているAPIライブラリである。
CORE
(モバイル、ウェブ、VMの総ての環境で使われる) |
dart:async |
エイシンクと発音。非同期処理関連のクラスたち |
dart:collection |
dart:coreでコレクションを補完するクラスとユーティリティ |
|
dart:convert |
文字コード、HTML、あるいはJSON処理等 |
|
dart:core |
コアとなるクラスと抽象クラスたちでインポート文は不要 |
|
dart:developer |
デバッガとうのツールをサポートする |
|
dart:math |
数値常数、関数、及び乱数 |
|
dart:typed_data |
固定サイズのデータ処理 |
|
WEB
(モバイル及びウェブ環境で使われる) |
dart:html |
HTML5ベースのDOM操作のクラスたちで、V8 JavaScript Engineの資産を取り込んだ大規模なライブラリ。クライアント用でサーバ側(Dart VM)には実装されない |
dart:indexed_db |
ブラウザのインデックスドDB処理 |
|
dart:js |
JavaScriptとの関わり合いを扱う |
|
dart:js_util |
型付けJSInteropオブジェクト操作用 |
|
dart:svg |
イベントとアニメーション対応の2次元ベクター・グラフィックス処理 |
|
dart:web_audio |
ブラウザ内でのHi-Fiウェブ・オーディオ |
|
dart:web_gl |
ブラウザ内での3Dウェブ・グラフィックス |
|
dart:web_sql |
SQLでアクセスできるブラウザ内でのデータのソート |
|
VM (VM環境専用) |
dart:cli |
|
dart:io |
サーバ側に必要なネットワーク・インターフェイス。スタンドアロンのDart VM専用 |
|
dart:isolate |
並行処理の為のアイソレートに関する関数及びクラスDart 2からVMのみとなった |
|
dart:mirrors |
Dart内でのベーシックなリフレクションでDart 2からVMのみとなった |
ライブラリの使い方はA Tour of the Dart Librariesという資料が参考になろう。
DartのAPIの特徴として次のものがあげられよう:
HTML5対応:
dart:htmlライブラリはChromeの蓄積を踏襲した巨大なもので、クライアント側で不自由を感じることは無いだろう。
非同期処理の為の多くの機能:
Dartは単一スレッドではあるが、殆どの処理はコールバック関数で記述された非同期処理で行われる。従ってスループットは大きい。Futureインターフェイスがその基本になっている。更にStreamというインターフェイスは連続したデータやイベントを取り扱う為の基本的なツールを提供している。
アイソレートによる並行処理:
必要ならIsolateインターフェイスを使ってマルチ・スレッド動作をさせることができる。各アイソレートが自分自身のヒープとスタックを持っており、アイソレート間はリソースを共有しないので、スレッド安全の問題が無い。アイソレート間はメッセージ通信で情報が交換される。しかしこの処理はブラウザには重いのでDart 2からはVM専用となってしまった。
開発のツールとしてパッケージ・マネージャ(Pub)や開発環境(IDE)などが用意されている:
Pubには多くの有用なパッケージが追加されてきている。特にAngularDart、ロガー、各種ミドルウエア、Googleアプリへのアクセス、DBドライバ等必要なものが揃っている。
サーバ側の為のライブラリ(dart:io)が強化されてきている:
サーバ・サイドにとってDartは魅力的な言語になりつつある。
Dart 2は常に改善がなされておりその詳細はgithubで見ることができる。
Dart 2の一番大きな変更点はその型システムの強化である:
Dart 2の型システムは完全な型システム(sound type system)である。従来Dart及びTypescripは"unsound type system”と称されてきた。型推論の導入で一般的な型に関わる問題が解決されている。
インスタンス生成のキーワードは一般的にオプショナルとなっている。詳細はusing-constructorsを見て頂きたい:
newは常にオプショナルである。
constはコンスタントのコンテキスト内でオプショナルである。
チェックド・モードはなくなった。
Assart文はまだサポートされているが、別のやり方でそれを実現できる。
Dart言語とコアのライブラリたちは変更となっているが、その一部は型システムの変更に伴うものである。
その他の大きな変更点としては、より大規模ウェブ・アプリケーションへの志向が進んだことであろう。これはDartの一番のユーザであるGoogleのサービスの開発者たちのフィードバックを取り込んでいるからであろう:
ブラウザのJavaScriptでの実行ではプログラムのサイズと速度の点で問題がある為"dart:isolate"と"dart:mirrors"はウェブ・アプリケーションでは諦め、VM専用としてdart:ioライブラリでのみ使用可能とした。(v2.0.0)ブラウザ上で並行処理を行わせるにはdart:htmlの中のwebworkersが使用できる。
Dart 2よりも前(M3版)の話ではあるが、文字列の文字コードUTF-16のコード単位(code units)の並びとした。以前の仕様書では文字列としてUnicode Normalization Form C(Unicode正規化形式C)に正規化すると書かれていたが、残念ながら現在はJavaなどと同じUTF-16となっている。これはJavaScriptへのクロス・コンパイルの制約からそうなったのだろう。
本来仕様書上では整数は固定した長さの域に制限されていない。Dartの整数は真の整数で、32ビットまたは64ビットあるいは他の固定域表現ではない。しかしながらJavaScriptに変換する制限から64ビットとすることは許されている。現在はそのような本来の整数はBigIntとしてdart:coreに残されている。
その他の変更点としては:
asncでアノテートされた関数は最初のawait文までの間は同期的に実行するようになった。従来はコードを実行する前にその関数のボディのトップでイベント・ループに戻るようになっていた。
コア・ライブラリにある常数は例えばGZIPからgzipとかJSONからjsonへとSCREAMING_CAPSからlowerCamelCaseに変更された。これはDart 1で書かれていたプログロムの多くが影響を受けている。
コアライブラリのクラスたちには多くのメソッドが追加されている。
pubのtransformerベースのビルドは新しいビルド・システムで置き換えられている。これはAngularDartのアプリに大きな影響を与える。
従来はDartコードのVMを実装したCromeブラウザであるDartiumで簡単にブラウザ上でそのアプリをテストできた。DartiumというのはGoogleがChromeの新しい版をリリースする前の状態のものをChroniumと呼んでいることからつけられた名前のブラウザである。しかしながらGoogleはChromeにDartのVMを実装することをあきらめてしまった為、これまでなんとか保守されてきていたDartiumを完全に放棄した。
推奨されるDartのコードの書き方は、当初DartチームのBob Nystromが書いたDart Style Guideやコーディング規約を見て頂きたいが、簡単にポイントを以下に示す。
インデントはスペース2文字であり、タブは使用しない。
一行の長さを80文字に留める。
左鍵カッコはそれが続いている行に含める。例:
class Foo {
method() {
if (true) {
2項や3項演算子の前後、及びカンマの後にスペースを置くが、単項演算子の前後には置かない。例:
a = 1 + 2 / (3 * -b);
c = !condition == a > b;
d = a ? b : object.method(a, b, c);
(, [, 及び {のあと、あるいは ), ], 及び }の前にはスペースを置かない
Dartにおいては以下の付名規約が一般的である:
コンパイル時定数変数の名前は小文字から始まる。もしそれらが複数の単語で構成されているときは、それらの単語をアンダスコアで分離させる。例えば:
const
D
efaultTimeout
= 1000;
ではなくてconst
defaultTimeout = 1000;
と書く
関数(ゲッタ、セッタ、メソッド、及びローカル及びライブラリ関数)と非定数変数の名前は小文字で始まる。もしそれらが複数の単語で構成されているときは、各単語(最初を除く)は大文字で始まる。それ以外には大文字は使わない。例:camlCase, , dart4TheWorld
型(クラス、型変数、及び型エイリアス)の名前は大文字で始まる。もしそれらが複数の単語で構成されているときは、各単語は大文字で始まる。それ以外には大文字は使わない。例:CamlCase, Dart4TheWorld
型変数の名前は短くする(一文字が好ましい)。例:T, S, K, V, E
ライブラリ、またはライブラリ・プレフィックスの名前は決して大文字を使わない。もしそれらが複数の単語で構成されているときは、それらの単語をアンダスコアで分離させる。例: my_favorite_library