アプリ開発日誌
2021.07.12
Flutter開発のためのDart入門(1)変数 型
はじめに
これから何回かに分けて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!
このコードにある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を代入できません。
次のコードはコンパイルエラーとなります。
void main() { int i = null; print(i); }
※null-safe(null 安全)については別の機会に詳しい記事を投稿する予定です。
abstract
やinterface
、class
などは予約語となっており、変数名などの識別子に使うことはできません。
予約語についてはこちらを参照してください。
もし値が変化しない事があらかじめ分かっているのなら、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型は浮動小数点に対応しています。
void main() { int a = 1; double pi = 3.14; }
int型とdouble型はnum型のサブクラスになります。
クラスについては今後の投稿で解説します。
文字列は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(ブール)型は真偽値を表し、true
とfalse
の2つの値のみ持ちます。
JavaScriptなどはfalseとして振る舞う値は数字の0
、null
、""
(空文字)などがありますが、Dartではこれらの値はfalse
として評価されません。
bool値のリテラルはtrue
とfalse
で、どちらもコンパイル時の定数です。
とてもシンプルでわかりやすいです。
if文やassert文にはtrue
かfalse
いずれかの値しか指定できません。
※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が提供されています。
※デフォルトでは順序が保持されます。
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
Unicodeは、世界中のすべての文字システムで使用されている各文字、数字、および記号に固有の数値を定義しています。
Dart文字列はUTF-16コード単位のシーケンスであるため、文字列内でUnicodeコードポイントを表現するには特殊な構文が必要です。Unicodeコードポイントを表現する通常の方法は、\uXXXX
で、ここでXXXX
は 4桁の16進数の値です。例えば、ハート文字 ♥ は、\u2665
です。
void main() { var heart = '\u2665'; print(heart); }
実行結果
♥
※Symbolについては利用する機会があまり無いため説明を省きます。
次回は関数について投稿する予定です。