Dart

出典: フリー教科書『ウィキブックス(Wikibooks)』
ナビゲーションに移動 検索に移動
Wikipedia
Wikipedia
ウィキペディアDartの記事があります。
メインページ > 工学 > 情報技術 > プログラミング > Dart
このページ「Dart」は、まだ書きかけです。加筆・訂正など、協力いただける皆様の編集を心からお待ちしております。また、ご意見などがありましたら、お気軽にトークページへどうぞ。

Dart(ダート)は、Googleが開発したスクリプト言語で、元々はJavaScriptを置き換えることを目的にしていました。 Googleは2011年までにChromeでDartVMをサポートすることを計画していましたが[1]、2015年にChromeへのDartVM統合を中止しました[2]。 その後、TypeScriptがGoogle社内の標準スクリプト言語として承認され、Dartは重要な言語であるものの、競合する言語となりました[3]

このように、ウェブブラウザ上のJavaScriptを置き換えることは失敗に終わったと見なされることがありましたが、2017年5月にGoogleが開発したオープンソースUISDKであるFlutterが登場したことで、Dartの状況は一変しました。 Flutterは、AndroidiOSLinuxmacOSWindowsGoogle Fuchsia[4]やウェブ向けのクロスプラットフォームアプリケーションを単一のコードベースから開発するために使用されるSDKです。 DartはFlutterのアプリケーション記述言語として採用され、Flutterと不可分の存在となりました。現在、DartはFlutterアプリケーションの記述に必要不可欠であり、言語仕様はFlutterアプリケーションのニーズに合わせて改定されています。

インストールしないで実行する方法[編集]

DartPad というサイトを使うと、自分の環境にインストールしないでもブラウザ上で Dart のプログラミングが行なえます。

https://try.dartlang.org/

インストール方法[編集]

Get the Dart SDK を入手できます。

Windowsの場合は、公式インストール方法ではパッケージマネージャーの Chocolatey を使うのですが日本では馴染みがないようなので、これとは別にコミュニティによる用意されたインストーラを使うと良いでしょう。⇒ https://gekorm.com/dart-windows/

動作確認[編集]

dartのバージョンは、

dart --version

で確認できます。

PS C:\Users\user1> dart --version
Dart SDK version: 2.15.0-168.0.dev (dev) (Thu Sep 30 12:23:13 2021 -0700) on "windows_x64"

のようにバージョン番号が出たら、成功です。

Hello World など[編集]

コード例
main() {
  print("Hello world");
}

print関数などのよく使われる関数はdart:coreライブラリにありますが、dart:coreライブラリはimport不要で使えます。

実行方法は、コマンドプロンプトあるいはWindows Terminalで、

dart ファイル名.dart

です。

変数[編集]

Dartには整数型や浮動小数型などの型があります。変数の宣言のときに型を明示する方法と、初期化する値から型を推論する方法があります。

型を明示する方法[編集]

main() {
  int a = 3;
  int b = 2 * a;
  print(b);
}
実行結果
6


初期化する値から型を推論する方法[編集]

Dartでは、型は var 宣言を使うことで型推論させることができます。

main() {
  var a = 4;
  var b = 1.23;
  print(a + b);
}
実行結果
5.23

定数を宣言する場合[編集]

main() {
  final List<int> a = [1, 2, 3];
  const List<int> b = [2, 3, 5];
  print(a + b);
  a[1] = 9;
  print(a + b);
  // b[0] = 0; ← final で宣言すると指し示す先のオブジェクトの値も変更できないので、この文はエラー
}
実行結果
[1, 2, 3, 2, 3, 5] 
[1, 9, 3, 2, 3, 5]
finalで宣言すると、初期化以降値を変更できない変数をつくれます。
finalで宣言された変数の指し示す先の値は変更できます。
constで宣言すると、初期化以降値を変更できない変数をつくれます。
constで宣言された変数は指し示す先の値も変更できません。

文字列への式の埋込み[編集]

文字列の中に、式を埋め込むことができます。

コード例
main() {
  var num = 4;
  print("num + 3 is ${num + 3}\n");
}
実行結果
num + 3 is 7

文字列の中に ${ 式 } の形式で埋込むと、実行時に展開されます。

文字列への変数の埋込み[編集]

文字列の中に埋込む式が単一の変数ならばより簡略化した形式で表現できます。

コード例
main() {
  var num = 4;
  print("num is $num\n");
}
実行結果
num is 4

文字列の中に $変数名 の形式で埋込むと、実行時に展開されます。

バックスラッシュ・エスケープ・シーケンス[編集]

改行などに対するバックスラッシュ・エスケープ・シーケンスは他のプログラミング言語と同様に使えます。

「\」そのものを表示したい場合は、先頭にもうひとつ「\」をつけて「\\」のようにするだけです。

コード例
main() {
  print("\\n");
}
実行結果
\n

コメント[編集]

コメントをソースコードに書くときは、//や、/**/を使用します。

1行で終わるコメント[編集]

下記コードのように//を使うと行末までがコメントになります。

コード例
main() {
  var cat = "Miku"; // 猫の名前
  print("The name of the cat is ${cat} \n");
}
実行結果
The name of the cat is Miku

複数行に渡るコメント[編集]

下記コードのように/**/で文を囲むと2行以上をコメントにできます。

コード例
main() {
  /* 動物の種類



  */
  var animals = ["cat", "dog", "rabbit"];
  print(animals);
}
実行結果
[cat, dog, rabbit]

関数[編集]

関数の定義と呼出し[編集]

関数は戻値の型と関数名と仮引数リストで定義します。 関数の呼出しは、関数名と実引数リストを与えます。

コード例
main() {
  int add(int x, int y) {
    int z = x + y;
    return z;
  }

  // add関数に引数として1と2を指定する。
  print(add(1, 2));
}
実行結果
3

ライブラリー[編集]

Dartには、様々な用途に特化した多くのライブラリーが存在します。以下は、Dartでよく使用されるライブラリーの一部です。

  1. dart:async - Dartの非同期処理を扱うためのライブラリー
  2. dart:math - 数学関数を提供するライブラリー
  3. dart:io - ファイル入出力やネットワーク通信を扱うためのライブラリー
  4. dart:convert - JSONやUTF-8などのエンコーディングやデコーディングを扱うためのライブラリー
  5. dart:html - Webアプリケーションを開発するためのHTML要素を提供するライブラリー
  6. http - HTTP通信を扱うためのライブラリー
  7. flutter - モバイルアプリケーションを開発するためのフレームワークであり、UIやネットワーク通信などの機能を提供するライブラリー

これらのライブラリー以外にも、様々な目的に特化したライブラリーが存在しています。Dartの公式ドキュメントや、Dart Pubと呼ばれるパッケージマネージャーで検索することで、必要なライブラリーを見つけることができます。

print関数などのよく使われる関数はdart:coreライブラリーにあり、dart:coreライブラリーはimportが不要ですが、それ以外のライブラリーはimportが必要です。

math ライブラリー[編集]

コード例
import 'dart:math';

num numval = pi;
main() {
  print(sin(pi / 4));
}
実行結果
0.7071067811865475
ライブラリーのimport
import 'dart:math';
num型
num numval = pi;
num型は、数値ならば整数型でも浮動小数点数型でも保持できる変数を宣言します。
ライブラリー関数の使用
  print(sin(pi / 4));

Dartの型システムの説明の前なので、簡単な例の説明に留めました。

制御構造[編集]

Dartには、if-else文、for文、while文、do-while文、switch文、forEachメソッドなど、多様な制御構造があります。

Dartプログラミング言語の主要な制御構造のチートシート
void main() {
  // if文
  int x = 10;
  if (x > 5) {
    print("x is greater than 5");
  } else if (x == 5) {
    print("x is equal to 5");
  } else {
    print("x is less than 5");
  }
  
  // forループ
  for (int i = 0; i < 5; i++) {
    print("i is $i");
  }
  
  // for-inループ
  List<int> numbers = [1, 2, 3, 4, 5];
  for (int number in numbers) {
    print("number is $number");
  }
  
  // whileループ
  int count = 0;
  while (count < 5) {
    print("count is $count");
    count++;
  }
  
  // do-whileループ
  int i = 0;
  do {
    print("i is $i");
    i++;
  } while (i < 5);
  
  // switch文
  String color = "red";
  switch (color) {
    case "red":
      print("color is red");
      break;
    case "green":
      print("color is green");
      break;
    case "blue":
      print("color is blue");
      break;
    default:
      print("color is not recognized");
      break;
  }
  
  // break文
  for (int i = 0; i < 5; i++) {
    if (i == 3) {
      break;
    }
    print("i is $i");
  }
  
  // continue文
  for (int i = 0; i < 5; i++) {
    if (i == 3) {
      continue;
    }
    print("i is $i");
  }
}
実行結果
x is greater than 5
i is 0
i is 1
i is 2
i is 3
i is 4
number is 1
number is 2
number is 3
number is 4
number is 5
count is 0
count is 1
count is 2
count is 3
count is 4
i is 0
i is 1
i is 2
i is 3
i is 4
color is red
i is 0
i is 1
i is 2
i is 4
i is 5
i is 0
i is 1
i is 2
i is 4
i is 5


for文とif文の組合わせ[編集]

for文とif文の組合わせ
main() {
  for (int i = 0; i < 10; i++) {
    if (i % 2 == 0) {
      print("$i は2の倍数です。");
    } else if (i % 3 == 0) {
      print("$i は3の倍数です。");
    } else {
      print("$i は2の倍数でも3の倍数でもありません。");
    }
  }
}
実行結果
0 は2の倍数です。
1 は2の倍数でも3の倍数でもありません。
2 は2の倍数です。
3 は3の倍数です。
4 は2の倍数です。
5 は2の倍数でも3の倍数でもありません。
6 は2の倍数です。
7 は2の倍数でも3の倍数でもありません。
8 は2の倍数です。
9 は3の倍数です。
for文
  for (int i = 0; i < 10; i++) {
C言語などと共通する三文式for文です。
最初の文は初期設定で変数の宣言もでき、宣言された変数のスコープはfor文が終わるまでです。
二番目の文は反復条件で、値はtrueかfalseである必要があり、trueであるかぎる続く文(内容としましょう)を反復します。
三番目の文は内容を実行したあと毎回評価されます。
if文
    if (i % 2 == 0) {
      print("$i は2の倍数です。");
    } else if (i % 3 == 0) {
      print("$i は3の倍数です。");
    } else {
      print("$i は2の倍数でも3の倍数でもありません。");
    }
i % 2は、「iを2で割った余り」を表す式で、条件式全体 i % 2 = 0は、「iを2で割った余りが0ならtrueそうでなければfalse」を表す式、、となります。
if文は条件式がtrueであればifに続く文を、(else節があれば)条件式がfalseならばelseに続く文を実行します。
if の条件式に一致せずelseがある場合はelseに続く文を実行しますが、if文も文なので } else if (i % 3 == 0) { のように続けて別の条件を評価することができます[5]

while文とif文の組合わせ[編集]

while文とif文の組合わせ
main() {
  int i = 0;
  while (i < 10) {
    if (i % 2 != 0) {
      print("$i は奇数です。");
    } else {
      print("$i は偶数です。");
    }
    i++;
  }
  print(i);
}
実行結果
0 は偶数です。
1 は奇数です。
2 は偶数です。
3 は奇数です。
4 は偶数です。
5 は奇数です。
6 は偶数です。
7 は奇数です。
8 は偶数です。
9 は奇数です。
10
while文とスコープ
  print(i);
上のfor文とif文の組合わせをwhileを使ってあらわあすと、概ねこのようになります。
「概ね」と言うのは、変数iのスコープは(while文の外で宣言しているので)main関数末まで続くので、while文を抜けても print(i);は有効です。

for文とswitch文の組合わせ[編集]

for文とswitch文の組合わせ
main() {
  for (int i = 1; i < 10; i++) {
    switch (i) {
      case 2:
      case 4:
      case 6:
      case 8:
        print("$iは、2の倍数です。");
        break;
      case 3:
      case 6:
      case 9:
        print("$iは、3の倍数です。");
        break;
      case 5:
        print("$iは、5の倍数です。");
        break;
      case 7:
        print("$iは、7の倍数です。");
        break;
      default:
        print("$iは、2,3,5,7のいづれの倍数でもありません。");
    }
  }
}
実行結果
1は、2,3,5,7のいづれの倍数でもありません。
2は、2の倍数です。
3は、3の倍数です。
4は、2の倍数です。
5は、5の倍数です。
6は、2の倍数です。
7は、7の倍数です。
8は、2の倍数です。
9は、3の倍数です。

forEachメソッド[編集]

forEachメソッドは、リストやマップなどのコレクションの各要素に対して指定した処理を実行するためのメソッドです。

forEachメソッド
void main() {
  List<String> fruits = ["apple", "banana", "orange"];
  
  // リストの各要素に対して、処理を実行する
  fruits.forEach((fruit) {
    print(fruit);
  });
}
上記の例では、List型のfruitsという変数に対してforEachメソッドを呼び出し、fruitsの各要素に対して、引数で指定された無名関数を実行しています。無名関数内では、printメソッドを使用して、各要素をコンソールに出力しています。

また、forEachメソッドは、以下のようにラムダ式を使用して簡略化することもできます。

forEachメソッドとラムダ式の組み合わせ
void main() {
  List<String> fruits = ["apple", "banana", "orange"];
  
  // リストの各要素に対して、処理を実行する(ラムダ式)
  fruits.forEach((fruit) => print(fruit));
}
上記の例では、引数で指定する無名関数をラムダ式で表しています。これにより、コードの記述量が簡略化されます。

for文とコレクションの組合わせ[編集]

for文とコレクションの組合わせ
main() {
  const array = [2, 3, 5, 7];
  print(array.runtimeType);
  for (var x in array) {
    print("for-in: $x");
  }
  array.forEach((item) {
    print("forEach: $item");
  });

  const set = {2, 3, 5, 7};
  print(set.runtimeType);
  for (var x in set) {
    print("for-in: $x");
  }
  set.forEach((item) {
    print("forEach: $item");
  });

  const map = {'apple': 'リンゴ', 'orange': 'オレンジ', 'banana': 'バナナ'};
  print(map.runtimeType);
  for (var key in map.keys) {
    print('$key : ${map[key]}');
  }
  for (var value in map.values) {
    print('for in map.values: $value');
  }
  map.forEach((var key, var value) {
    print('forEach: $key : $value');
  });
}
実行結果
JSArray<int>
for-in: 2
for-in: 3
for-in: 5
for-in: 7
forEach: 2
forEach: 3
forEach: 5
forEach: 7
_UnmodifiableSet<int>
for-in: 2
for-in: 3
for-in: 5
for-in: 7
forEach: 2
forEach: 3
forEach: 5
forEach: 7
ConstantStringMap<String, String>
apple : リンゴ
orange : オレンジ
banana : バナナ
for in map.values: リンゴ
for in map.values: オレンジ
for in map.values: バナナ
forEach: apple : リンゴ
forEach: orange : オレンジ
forEach: banana : バナナ

オブジェクト指向プログラミング[編集]

Dartはオブジェクト指向言語であり、クラスを使ってオブジェクトを定義できます。クラスはフィールドとメソッドを持ち、フィールドはオブジェクトの状態を表し、メソッドはオブジェクトの振る舞いを定義します。

以下は、Dartでクラスを定義し、オブジェクトを作成する例です。例として、Personクラスを定義し、名前と年齢をフィールドに持ち、年齢を1歳増やすメソッドを定義します。また、main関数で2つのPersonオブジェクトを作成し、1つのオブジェクトの年齢を増やして表示します。

クラスの例
// Personクラスの定義
class Person {
  String name; // 名前
  int age; // 年齢
  
  // コンストラクタ
  Person(this.name, this.age);
  
  // 年齢を1歳増やすメソッド
  void incrementAge() {
    age++;
  }
}

void main() {
  // Personオブジェクトの作成
  var person1 = Person('Alice', 20);
  var person2 = Person('Bob', 25);
  
  // person1の年齢を1歳増やす
  person1.incrementAge();
  
  // person1とperson2の情報を表示する
  print('Person 1: ${person1.name}(${person1.age})');
  print('Person 2: ${person2.name}(${person2.age})');
}
実行結果
Person 1: Alice(21) 
Person 2: Bob(25)
まず、Personクラスが定義されています。このクラスには、名前と年齢を表すString型のnameフィールドとint型のageフィールドが含まれています。また、このクラスには、名前と年齢を引数として受け取るコンストラクタと、年齢を1歳増やすメソッドincrementAgeが含まれています。
次に、main関数では、2つのPersonオブジェクトを作成し、1つのオブジェクトの年齢を増やしています。varキーワードを使って、Personオブジェクトを作成しています。Person('Alice', 20)は、Personクラスのコンストラクタを呼び出し、nameを'Alice'、ageを20で初期化しています。
その後、person1オブジェクトのincrementAge()メソッドが呼び出され、その結果、person1オブジェクトのageフィールドが1増えます。
最後に、person1person2の情報を表示するために、print()関数が使用されます。それぞれのオブジェクトの名前と年齢が表示されます。

継承[編集]

継承は、既存のクラスを基にして新しいクラスを定義することができます。

継承の例
// Personクラスの定義
class Person {
  String name; // 名前
  int age; // 年齢
  
  // コンストラクタ
  Person(this.name, this.age);
  
  // 年齢を1歳増やすメソッド
  void incrementAge() {
    age++;
  }
}

void main() {
  // Personオブジェクトの作成
  var person1 = Person('Alice', 20);
  var person2 = Person('Bob', 25);
  
  // person1の年齢を1歳増やす
  person1.incrementAge();
  
  // person1とperson2の情報を表示する
  print('Person 1: ${person1.name}(${person1.age})');
  print('Person 2: ${person2.name}(${person2.age})');
}
実行結果
Tama is eating. 
Meow!
この例では、Animalという親クラスが定義され、nameというインスタンス変数とeat()というメソッドが定義されています。そして、Catという子クラスがAnimalを継承しています。Catnameを引数に取るコンストラクタとmeow()というメソッドを持っています。
main関数では、Catのインスタンスであるcatを作成し、eat()meow()メソッドを呼び出しています。eat()メソッドはAnimalクラスから継承されたもので、meow()メソッドはCatクラスで定義されたものです。

脚註[編集]

  1. ^ Google Operating System: Dash, Google's Alternative to JavaScript
  2. ^ ChromeへのDartVM統合を断念、Dart開発チームが発表。今後はJavaScriptへのコンパイルにフォーカス”. Publickey (2015年3月26日). 2017年4月15日閲覧。
  3. ^ TypeScriptが標準言語になっても、Dartのことは忘れてませんよとGoogle担当者がフォロー”. Publickey (2017年4月12日). 2017年4月15日閲覧。
  4. ^ Google's "Fuchsia" smartphone OS dumps Linux, has a wild new UI”. Ars Technica.テンプレート:Cite web/error
  5. ^ 他の言語では、elseifやelsifなどの特別な表現を用意している場合がありますが、Dartは「else節に対応する文がif文」と表現します。

外部リンク[編集]