こんにちは!tatata-keshiです![]()
みなさんは Dart を触っている際にこのような疑問を感じたことはありませんか?
「あれ、文字列型は String なのに、整数型は int。なぜ型によって頭文字の大文字・小文字がバラバラなんだろう?」
今回は、その理由と背景について調べてみました。
Dart の型は「すべてオブジェクト」 — “クラスベース” の型システム
まず前提として、Dart は すべての変数がオブジェクト(クラスのインスタンス)を参照する 言語です。
つまり、たとえ数値型の int であっても、プリミティブ値ではなく、オブジェクトとして扱われます。
文字列(String)、数値(int, double, num)、ブール(bool)、コレクション(List, Map など)もすべてオブジェクトです。
そのため、Dart では「型名 = クラス名」という扱いでも矛盾はなく、理論上は String や List をクラスとして定義するのは自然です。
このようなオブジェクト指向+型安全な言語設計のもとで、「型名としてクラス名をどう扱うか」という命名規則が生まれます。
命名規則と慣習 — UpperCamelCase と lower-case 型名の混在
Dart では、識別子(クラス名、変数名、関数名 など)に対して 命名規則(スタイルガイド) が定められています。
- UpperCamelCase — 各単語の頭を大文字にし、先頭も大文字。たとえばクラス名や型名。
- lowerCamelCase — 先頭は小文字、以降の単語の頭は大文字。たとえば変数名、関数名など。
したがって、理屈としては、型名(=クラス名)は UpperCamelCase にした方が自然です。実際に String, List, Map など多くの型はこの形です。
しかし一方で、なぜか int, double, bool, num, dynamic, void など、小文字の型名も混在しています。これは “歴史的な互換性” と “他言語からの慣れ” を反映したものだと考えられています。
実際、GitHub の Dart SDK の issue(議論)でもこの “不整合な大文字小文字” が指摘されています。言語本来の設計では「すべてクラス/オブジェクト」として扱っているにも関わらず、なぜか int や double だけ小文字のまま――というのは「歴史的な名残」だ、というコメントがあります。
なぜ “歴史的な名残” が残されたのか?
ではなぜ、あえて int や double のように “小文字の型名” を残したのでしょうか?主に以下のような理由が考えられます:
他言語(特に C / C++ / JavaScript / Java など)から乗り換える人の慣れ を重視。int, double, bool などは多くの言語で小文字あるいはプリミティブ型だった。Dart でもそのまま使えることで学習コストを低減。
Dart が最初から “すべてオブジェクト” の言語ではあったものの、言語設計の初期から「プリミティブ的な数値型、真偽値型」などの読みやすさや慣習を尊重した。結果として、型名が一律ではなく混在するスタイルが受け入れられた。
既存コードとの互換性。もし後から Int や Double のように大文字始まりに変えると、既存コードとの互換性で混乱が起こる可能性がある。過去の歴史を尊重するため、小文字の型名が残された。
たとえば――コードで見るとこう
// 文字列型(UpperCamelCase)
String name = 'Taro';
// 整数型(lower-case)
int age = 30;
// 浮動小数点数型(lower-case)
double height = 1.75;
// ブール型(lower-case)
bool isActive = true;
// リスト(UpperCamelCase + ジェネリクス型)
List<String> tags = ['flutter', 'dart'];
このように、UpperCamelCase と lower-case が混在しても、Dart の型システム上ではどちらも “クラス/オブジェクト型” として振る舞います。実行時に動的なオブジェクト参照である点に変わりはありません。
まとめ — 混在は「デザインの妥協」の結果
Dartの型名の頭文字に大文字と小文字が混在しているのは、 Dart が採る「オブジェクト指向+型安全」な設計と、他言語からの学習コスト・互換性を考えた「命名習慣との妥協」の結果であるといえます。