アプリエンジニアが教えるわかりやすいDart入門(1)変数 型

Dart_programming_language_logo

はじめに

これから何回かに分けてDart言語についてなるべくわかりやすく解説していきます。

対象読者は簡単なプログラミングの書籍を一冊程度読んだことがある方を想定しています。

おそらくDartを学びたいと思っている方は、Flutterでモバイルアプリを作ってみたいという方が多いかと思います。

Flutterでアプリ開発をするにはDartの基礎を理解する必要があります。

そんな方々のお役に立てれば幸いです。

公式サイトはこちらです。

この記事は、主に上記サイト内にある A tour of the Dart languageなどを参考にしています。

解説するバージョンはDart 2.13です。

今回は以下の内容を解説します。

  • DartPad
  • 変数

DartでHello, World!

まずコードの確認ですが、DartPadという便利なもがあります。

こちらを使えばブラウザ上でコードの確認が簡単におこなえます。

エディタでオススメするのは「Visual Studio Code」です。

インストールしたら、Visual Studio Codeを起動し、ウインドウの左端にあるアイコンから、「機能拡張」のアイコンをクリックして下さい。

そして、検索フィールドから「Dart Code」と「Code Runner」というプラグインを検索し、インストールしておきます。

今回はDartPadを使っていきます。

Hello, World!を表示するコードは次のようになります。

// main関数からアプリが実行されます。
void main() {
  print('Hello, World!');
}

DartPadに上記のコードをペーストして「Run」ボタンを押すと、コンソールに実行結果が表示されます。

実行結果

Hello, World!

dartpad1

このコードにあるmain()ですが、JavaScriptなどのスクリプト系言語を学ばれた方には、あまり馴染みが無いかもしれません。
こちらはmain()関数と言い、C/C++やJava(C#ではMain)がこのような仕様となっています。
まず最初にこちらが実行されます。(一般的にエントリーポイントと呼ばれています)
main()を書かないとプログラムが実行されません。

コメント

1行のコメントは//スラッシュを2つ続けます。

行末までコンパイラに無視されます。

// これはコメントです。

複数行のコメント開始は、スラッシュの後にアスタリスクを配置します。

コメント終端はアスタリスクの後にスラッシュを配置します。

/**/の間はすべてコンパイラによって無視されます。

/*
  これは
  複数行の
  コメントです。
*/

変数

Hello, World!を変数greetingに代入して表示しています。

void main() {
  var greeting = 'Hello, World!';
  print(greeting);
}

実行結果

Hello, World!

varを指定すると、型推論がおこなわれます。

var greeting = 'Hello, World!';

Dartはオプショナルタイピングを採用しています。
これは型を明示的に指定することもできますし、varで型を明示的に指定しない選択ができるということです。
varで宣言した変数greetingは、型推論によりString型として扱われます。
isキーワードで実行時における型をチェックできます。

void main() {
  var greeting = 'Hello, World!';
  print(greeting is String);
}

実行結果

true

型推論されたString型変数greetingに整数を代入するとコンパイルエラーとなります。

void main() {
 	var greeting = 'Hello, World!';
 	greeting = 1;	// Error
}

変数の宣言時にString型で明示的に型を指定した例です。
これを型アノテーション(注釈)と言います。

void main() {
  String greeting;
  greeting = 'Hello, World!';
  print(greeting);
}

実行結果

Hello, World!

変数なので再代入が可能です。

void main() {
  String greeting;
  greeting = 'Hello, World!';
  print(greeting);
  greeting = 'Hello, Dart!’;
  print(greeting);
}

実行結果

Hello, World!
Hello, Dart!

型が決定されていないことを明示的に伝えたい場合は、dynamic型を指定します。

dynamic greeting = 'Hello, World!';

変数の補足

null-safe(null安全)

Dart 2.12 がリリースされて null-safe(null安全)な言語となりました。
Sound null safety
Understanding null safety

DartPad画面下部にNull Safety のトグルスイッチがONで表示されているかと思います。
Null SafetyがONの状態だと、変数のデフォルト値にnullを代入できません。

dartpad-img

次のコードはコンパイルエラーとなります。

void main() {
  int i = null;
  print(i);
}

※null-safe(null 安全)については別の機会に詳しい記事を投稿する予定です。

予約語

abstractinterfaceclassなどは予約語となっており、変数名などの識別子に使うことはできません。
予約語についてはこちらを参照してください。

定数

もし値が変化しない事があらかじめ分かっているのなら、finalキーワードを使うべきです。

finalキーワードをつけ、型を指定しない例です。

void main() {
  final greeting = 'Hello, World!';
  print(greeting);
}

finalキーワードをつけ、型アノテーションを指定した例です。

void main() {
  final String greeting = 'Hello, World!';
  print(greeting);
}

finalで宣言された変数は定数として扱われるため、一度値を格納した後は変更することはできません。
次のコードはコンパイルエラーとなります。

void main() {
  final String greeting = 'Hello, World!';
  greeting = 'Hello, Dart'; // Error
  print(greeting);
}

定数を宣言するキーワードは、finalのほかにconstがあります。
constで宣言された変数は、コンパイル時に評価される定数です。
※constについてはまた別の機会に詳しく投稿する予定です。

Dart言語のビルトインタイプ(あらかじめ組み込まれている型)は以下になります。

  • 数字(int、double)

  • 文字列(String)

  • ブール値(bool)

  • リスト(List)

  • セット(Set)

  • マップ(Map)

  • ルーン(Runes)

  • シンボル(Symbol)

これらはリテラルを使って初期化することができます。
※リテラルとはコードに直接書き込んだ値のことです。
例えば、'this is a string'は文字列リテラルで、trueは真偽値リテラルです。

int, double

int型は整数値、double型は浮動小数点に対応しています。

void main() {
  int a = 1;
  double pi = 3.14;
}

int型とdouble型はnum型のサブクラスになります。
クラスについては今後の投稿で解説します。

String

文字列はString型を使用します。
シングルクォーテーション’…’ 、またはダブルクォーテーション”…”で文字列を式の中に入れることができます。

void main() {
  String s1 = 'The Dart language is type safe';
  print(s1);
  String s2 = "Sound null safety";
  print(s2);
}

実行結果

The Dart language is type safe
Sound null safety

複数行の文字列はシングルクォーテーションを3つ重ねます。

void main() {
  String s = '''
  これは
  複数行の
  文字列です。
  ''';
  print(s);
}

実行結果

これは
複数行の
文字列です。

式の値を文字列の中に入れるには${変数名}、または{}を省略して$変数名を使います。

void main() {
  var name = 'Satoshi';
  var greeting = 'Hello ${name}';
  print(greeting);
}

実行結果

Hello Satoshi

bool

bool(ブール)型は真偽値を表し、truefalseの2つの値のみ持ちます。
JavaScriptなどはfalseとして振る舞う値は数字の0null""(空文字)などがありますが、Dartではこれらの値はfalseとして評価されません。
bool値のリテラルはtruefalseで、どちらもコンパイル時の定数です。
とてもシンプルでわかりやすいです。
if文やassert文にはtruefalseいずれかの値しか指定できません。
※if文やassert文については今後の投稿で解説します。

void main() {
  // ゼロのチェック
  var hitPoints = 0;
  assert(hitPoints == 0);

  // nullのチェック
  var unicorn = null;
  assert(unicorn == null);

  // 空文字のチェック
  var fullName = "";
  assert(fullName.isEmpty);
}

List

まとまりを持った順序のある値を扱う場合、Listが提供されています。
JavaのようにArray(配列)とListがある訳ではありません。
次のコードはシンプルなListの例です。

void main() {
  var list = [1, 2, 3];
  print(list);
}

実行結果

[1, 2, 3]

明示的に型を指定してListを作成する事もできます。
その場合は<>内に型を指定します。

void main() {
  List<int> list1 = [1, 2, 3];
  print(list1);
  List<String> list2 = ['One', 'Two', 'Three'];
  print(list2);
}

実行結果

[1, 2, 3]
[One, Two, Three]

個別に値を取得するにはインデックス(添字)を指定します。
インデックスは0から始まります。

void main() {
  var list = [1, 2, 3];
  print(list[0]);
}

実行結果

1

インデックスを使って任意の位置に値を代入する事もできます。

void main() {
  var list = [1, 2, 3];
  list[0] = 0;
  print(list);
}

実行結果

[0, 2, 3]

指定したインデックスが配列内にない場合、実行時エラーになります。
※実行時エラーの確認はDartPadではおこなえません。

void main() {
  var list = [1, 2, 3];
  print(list[3]);	// RangeError (index): Invalid value: Not in inclusive range 0..2: 3
}

Listのプロパティ(属性)やメソッドについては、今後の投稿で解説します。

Set

順序付けられていないユニークな(重複を許さない)値のまとまりを扱う場合、Setが提供されています。
※デフォルトでは順序が保持されます。

void main() {
  var emails = {'[email protected]', '[email protected]', '[email protected]'};
  print(emails);
  // 同じ値を追加
  emails.add('[email protected]');
  print(emails.length);
}

実行結果

{[email protected], [email protected], [email protected]}
3

Map

関連付けたキーと値のまとまりを扱う場合、Setが提供されています。
キーはユニークである必要があり重複は許されません。

void main() {
  var languages = {
    // キー  : 値
    'Dart'  : 2011,
    'Kotlin': 2011,
    'Swift' : 2014,
  };
  print(languages);
}

実行結果

{Dart: 2011, Kotlin: 2011, Swift: 2014}

Mapに新しいキーと値のペアを追加する例です。

void main() {
  var languages = {
    // キー  : 値
    'Dart'  : 2011,
    'Kotlin': 2011,
    'Swift' : 2014,
  };
  print(languages);
  languages['Go'] = 2009;
  print(languages);
}

実行結果

{Dart: 2011, Kotlin: 2011, Swift: 2014} 
{Dart: 2011, Kotlin: 2011, Swift: 2014, Go: 2009}

Mapから値を取り出すには対応するキーを指定します。

void main() {
  var languages = {
    // キー  : 値
    'Dart'  : 2011,
    'Kotlin': 2011,
    'Swift' : 2014,
  };
  print(languages['Dart']);
}

実行結果

2011

Mapに指定したキーがない場合、nullが返ります。

void main() {
  var languages = {
    // キー  : 値
    'Dart'  : 2011,
    'Kotlin': 2011,
    'Swift' : 2014,
  };
  print(languages['Rust']);
}

実行結果

null

Runes

Unicodeは、世界中のすべての文字システムで使用されている各文字、数字、および記号に固有の数値を定義しています。
Dart文字列はUTF-16コード単位のシーケンスであるため、文字列内でUnicodeコードポイントを表現するには特殊な構文が必要です。Unicodeコードポイントを表現する通常の方法は、\uXXXXで、ここでXXXXは 4桁の16進数の値です。例えば、ハート文字 ♥ は、\u2665です。

void main() {
  var heart = '\u2665';
  print(heart);
}

実行結果

※Symbolについては利用する機会があまり無いため説明を省きます。

次回は関数について投稿する予定です。

たかひら かずま
ウォーキングをしながら音楽を聴いたり考えごとをするのが好きです。
最近リモートワークで太ってしまったのでダイエットに挑戦中!

Egg Device Application

東京品川のスマホアプリ製作・開発会社です。
一般アプリ業務用アプリからVRアプリまで開発可能。

求人情報

スマホアプリ製作・開発の
相談を受け付けています

メールでのご相談

お電話でのご相談
TEL 03-5422-7524
平日10:00~18:00