【Dart入門】基礎文法とサンプルコード集

Dartの基礎文法とサンプルコードについて入門者向けにまとめました。

【Dartとは】開発環境の構築

Dart(ダート)とは、Googleが開発したWebアプリケーション開発向けのオブジェクト指向型プログラミング言語です。
2011年に発表され、当初は「Dash」と呼ばれていました。
近年は、Flutterと呼ばれる「AndroidとiPhoneのアプリ開発を行えるフレームワークのプログラミング言語」としてDartが注目されています。

関連記事
応用例 【Flutter入門】iOS、Android、Windowsアプリ開発

【基本構造】メイン関数と標準出力

まず、Dartで定番の「Hello, world!」を行います。
以下の内容をファイル(hello.dart)に保存します。

void main(){
    print('Hello, world!');
} 

そして、次のコマンドで実行し、「Hello, world!」と出力されれば OK です。

$ dart hello.dart 

Hello, world!

これが、Dartの基本的なプログラムの構造となります。
main(){~}は「main関数」と呼ばれるもので、プログラムを実行したときに、最初に実行されるものです。
Dartでは、プログラムを作成する際には、必ずこのmain関数を用意し、その中に処理を書きます。

また、Dartでは一行の関数は、次のように一行で記述することができます。

main() => print('Hello, world!');

なお、main 関数は入力引数を List として受け取ることができます。

ちなみに、Dartの標準出力にはcoreライブラリの中にあるprint関数を使用します。
今回は文字列(’Hello, world!’)を入れましたが、「$変数名」とすると、その変数の内容を出力できます。
変数については後ほど詳しく説明します。

【標準入力】

【変数】データ型の種類、代入・参照

Dartでは、変数の型を指定することが可能です。

種別 概要
num 数値
int 整数
double 実数
bool 論理値
String 文字列
List リスト
Map マップ

値の代入は他のプログラミング言語と同じくイコール(=)を使います。

■データ型を指定して変数に代入する例(文字列型:String)

String msg = 'Excalibur'; 

JavaScriptと同じく、データ型を指定せずに変数を宣言する場合は「var」を使います。

var msg = 'Excalibur'; 

値を代入せずに変数を宣言したい場合、変数には「null」が入っています。
(Javascriptだと「undefined」)

var msg; // null 

定数(変更を許可しない変数)を宣言する場合は「final」キーワードを用います。

final String msg = 'Excalibur'; // null 

複数の変数に同時に同じ値を代入することも可能です。

void main(){
    var x, y;

    x = y = 1;

    print(x); // 1
    print(y); // 1
} 

【制御構文】for文、while文、if文

【関数】引数、名前付き引数、デフォルト引数

関数とは、「処理のまとまり」のことです。
プログラムの規模が大きくなるほど、関数で処理を分けて記述した方が、効率的で分かりやすいコードを書くことができます

関数と引数

void myfunc(double x, path) {
  // ...
} 

myfunc(10, "C\");

名前付き引数

引数を{}で囲むことで名前付き引数を定義できる

void myfunc({double x, string path}) {
  // ...
} 

myfunc(x: 10, path: "C\");

オプション引数

String myfunc(double x, String path, [String optio]) {
  // ...
} 

オプション引数とは、関数呼び出し時に値を渡さなくても呼ぶ出すことができる引数です。
引数を[]で囲むと、オプション引数となります。

デフォルト引数

Dartの関数では、デフォルト引数(関数呼び出し時に引数に値が渡されなかったときに使用する初期値)も利用できます。

void myfunc1({double x = 10,  String path = "C\"}) {
  // ...
}

String say(double x = 10, double y = 20,
    [String path = "C\", String hogu = "Excalibur"]) {
 //...
}

void myfunc3(
    {List points = const [1, 2, 3],
    Map items = const {
      'first': 'paper',
      'second': 'cotton',
      'third': 'leather'
    }}) {
// ...
} 

【Collections】lists、maps、queues、sets

Collections、objectを格納するAPIで、lists、maps、queues、setsの4種類があります。

lists

一般的なリスト型オブジェクトです。
順番があり、indexからデータの操作(参照、検索、追加、削除など)が可能です。

import 'dart:collection';

void main() {
    // リストの定義
    var names = ['savar', 'archer', 'lancer'];
    
    // 0番目の要素を参照
    print(names[0]); // savar

    // 要素を追加
    names.add('caster');

    // 要素数(配列の長さ)を参照
    names.length == 4;
    
    // aから始まる要素を取得
    names.where((f) => f.startsWith('a')).toList();
} 

maps

一般的には、連想配列や辞書型と呼ばれるものです。
key(キー)とvalue(値)を持っており,keyによってデータの操作(参照、検索、追加、削除など)が可能です。
keyにはnull以外のオブジェクトを利用できます。

import 'dart:collection';

void main() {
    var item = {
        'first': 1, // Key:    Value
        'second': 2,
        'fifth': 3
    };
}  

queues

queuesはlistsと同じく順番があり、最初と最後に追加もしくは削除できます。
しかしindexがないため、真ん中の要素は触ることができません。

sets

要素の順序はないが、要素は同じ値を複数入れることができません。
要素の値を被らせたくない場合に使用します。

【オブジェクト指向】クラス

コンストラクタ

コンストラクタ(初期化メソッド)を定義するには、クラス名と同じ関数を定義します。

class MyClass {
  num x, y;

  MyClass(num x, num y) {
    this.x = x;
    this.y = y;
  }
} 

void main() {
  var my = MyClass(10, 20);
  print(my.x); // 10
} 

名前付きコンストラクタを定義してクラスのコンストラクタを複数定義できます。

class Point {
  num x, y;

  Point(this.x, this.y);

  // 名前付きコンストラクタを定義
  Point.origin() {
    x = 0;
    y = 0;
  }
} 

スーパークラスのコンストラクタ、名前付きコンストラクタはサブクラスには継承されないため、サブクラスで名前付きコンストラクタを使用する場合はそのコンストラクタをサブクラスに実装する必要があります。

インスタンス変数の初期化

コンスタラクタの実行前にインスタンス変数を初期化できます。

// 名前付きコンストラクタ
MyClass.fromJson(Map json)
    : x = json['x'],
      y = json['y'] {
  print('In Point.fromJson(): ($x, $y)'); // :でイニシャライザを区切る
} 

getter/setter

getter/setter(ゲッター/セッター)を定義されたクラスのメンバーは、あたかもメンバー変数と同じようにアクセスでき、さらにほかの処理を追加することもできます。
つまり、オブジェクトのプロパティへの読み書きアクセスを提供するメソッドです。
それぞれのインスタンス変数には暗黙的にゲッターとセッターがありますが、getキーワードとsetキーワードを使用してgetter,setterを実装することもできます。

class MyClass {
  num x, y, w, h;

  MyClass(this.x, this.y, this.w, this.h);

  num get right => x + w;
  set right(num value) => x = value - w;
  num get bottom => y + h;
  set bottom(num value) => y = value - h;
} 

クラス変数/クラスメソッド

staticキーワードを使用してクラス変数、クラスメソッド(静的変数、静的メソッド)を定義できる

class MyClass {
  num x, y;
  MyClass(this.x, this.y);

  static num myMethod(MyClass w, MyClass h) {
   //...
  }
}

void main() {
  var my = MyClass.myMethod(w, h);
} 

ライブラリの使用

importキーワードでライブラリを読み込むことができます。
また、Pythonと同じくasを用いることで接頭語を指定できます。

import 'package:lib1/mylib1.dart';
import 'package:lib2/mylib2.dart' as lib2;

Element element1 = Element();

lib2.Element element2 = mylib2.Element();

【非同期処理】async/awaitによる非同期処理の実装

非同期処理と同期処理の違いは以下のとおりです。

種別 概要
非同期処理 あるタスクの実行中に、他のタスクが別の処理を実行できる方式。
同期処理 あるタスクの実行中に、他のタスクの処理は中断される方式。

DartではFuture/async(JavaScriptでいうPromise)と「await」もしくは「then」で非同期処理を実装できます。
ただし、thenのほうが可読性が低いためasync/awaitのほうが使いやすいです。

キーワード 概要
await 非同期処理を行うメソッドの呼び出し時に追記することで、メソッド内部の非同期処理の完了を待つ。(メソッドの内容が非同期処理であっても、メソッド内の処理が完了するまでその先に処理に進まない)
Future Futureクラスを利用すると、Future クラスに渡した処理を非同期で処理することができる。Future クラスに渡した処理は、処理が呼び出されつつも、呼び出し元では完了を待たずにその先に処理が進む。
async asyncがつけられたメソッドの内容は非同期で処理される。(メソッドが呼び出されつつも、呼び出し元ではメソッドの完了を待たずにその先に処理が進む)

awaitの例

import 'dart:async'; // dart:asyncをインポート

// 実行箇所にasyncを宣言
void main() async {
  print(new DateTime.now());
  // new Future.delayed() の前にawaitを書く
  var now = await myfunc();
  print(now);
}

Future <String> myfunc(){

  return new Future.delayed(new Duration(seconds: 10), (){
    return new DateTime.now().toString();
  });
} 

/*
2019-07-27 08:34:52.262
2019-07-27 08:35:02.264
/*

thenの例

import 'dart:async';

void main() async {
  print(new DateTime.now());
  myfunc()
    .then((now) {
      print(now);
    });
}

Future <String> myfunc(){
  return new Future.delayed(new Duration(seconds: 10), (){
    return new DateTime.now().toString();
  });
} 
/*
2019-07-27 08:34:52.262
2019-07-27 08:35:02.264
/*
関連記事
1 【Dart】非同期処理の実装(Future/async/await)

【その他】ファイル処理、アプリ作成、参考文献

時刻 西暦、和暦、年齢、干支の相互変換
ファイル処理 【Dart入門】ファイルの読み書き操作(text、csvなど)
アプリ開発 【Flutter入門】iOS、Android、Windowsアプリ開発
パッケージ公開 自作パッケージをpub.devに公開
入門サイト 初心者のためのDart 2入門
関連記事