第2回:基本的なコーディング知識と実習

Flutterを使ったアプリ開発で利用する、Dart言語とそのプログラミングについて学びます。

利用する環境:DartPad

Dart言語の学習は、DartPadというウェブブラウザ上で動作する開発環境で行います。 ウェブブラウザだけで簡単なプログラムを実装することができます。

DartPad

①エディターエリア:コードを記述するスペースです。

②実行ボタン:①で記述したコードを実行するためのボタンです。

③コンソールエリア:②で実行されたコードの結果が表示されるスペースです。

④ドキュメントエリア:①のコードにカーソルを合わせると、関連する関数のドキュメントが表示されます。

⑤サンプルコード:DartPadが準備しているサンプルコードを表示します。任意のサンプルコードを選択すると、①にサンプルコードが反映されます。

Dartとは?

Dartは高速なアプリケーション開発と実行のために最適化されたプログラミング言語で、オブジェクト指向、クラスベース、ガベージコレクションを備えたCスタイルの言語です。

Dartのロゴ

2011年にGoogleによって Dart 発表され、オープンソース(BSDライセンス)として運用されています。発表当初は、JavaScript(ウェブブラウザ埋め込みスクリプト言語の一つ)の代替として、JavaScriptの言語上の問題解決、パフォーマンス向上、セキュリティー向上を目的に設計・開発された言語です。 2018年2月に Dart2 が発表され、Dart2 では、ウェブアプリやモバイルアプリといった、クライアント開発に重点が置かた仕様となっています。

Dart2は、特にクライアントのアプリケーション開発に最適化されており、ウェブ・モバイル・デスクトップなどの多様なプラットフォーム向けアプリケーションの、開発(秒単位のホットリロード)と高品質な制作環境の両方を提供しています。また、最終的な製品段階では、モバイル・デスクトップ・バックエンド用のARMおよびx64マシンコードにコンパイルできます。ウェブ版は、Web用のJavaScriptにコンパイルします。

引用1 引用2 引用3 引用4

基礎知識

サンプルコードをDartPadで実行しながらDartの基本的な動作を確認します。 まずは、以下のコードを①に貼り付けて②を押して、③に「Hello World!」の文字が表示されることを確認してください。

void main() {
    print("Hello World!");
}

Dartプログラムは、main関数から実行されます。 また、文末には;(セミコロン)が必要があり、入力しない場合はエラーになります。 PythonやKotlin、Swiftなどはセミコロン無しでも動作しますが、Dartでは入力する必要があります。

変数宣言

Dartは、以下のデータ型をサポートしています。 またDartでは全てがオブジェクトのため、Javaのプリミティブ型のようなものは存在しません。 すべてのオブジェクトは、Objectクラスを継承しています。

  • Numbers (int, double):数値
  • Strings (String):文字列
  • Booleans (bool):真偽値
  • Lists (List, also known as arrays):配列型
  • Sets (Set):集合型
  • Maps (Map):辞書型
  • Object (Object)
  • The value null (Null)

詳細

変数(推定型)としてvarを利用できます。 代入した値に応じた型が自動的に推定されます。

void main() {
    var textVal = 'apple';
    var intVal = 1;
    var doulbeVal = 1.1;
    var boolVal = true;
    var listVal = [1,2,3];    
    var mapVal = {"a":1, "b":2}; 
    print("$textVal, $intVal, $doulbeVal, $boolVal, $listVal, $mapVal");
}

静的な型づけはオプショナルですが、明示的に型を宣言することもできます。

void main() {
    String textVal = 'apple';
    int intVal = 1;
    double doulbeVal = 1.1;
    bool boolVal = true;
    List listVal = [1,2,3];    
    Map mapVal = {"a":1, "b":2}; 
    print("$textVal, $intVal, $doulbeVal, $boolVal, $listVal, $mapVal");
}

定数宣言

定数として、finalconstを利用できます。 型を指定しない場合は、varと同様に推定型として処理されます。

void main() {
    final orange = 'orange';
    const banana = 'banana';
    final String melon = 'melon';
    const String peach = 'peach';
}

コメントアウト

///* */ を用いることで、コードをコメントアウト(実行しないコードに設定する)することが可能です。

void main() {
    // print("Hello World!") 
    
    /*
    print("Hello World!") 
    */
}

制御フロー

制御フローとして、その他多くのプログラミング言語でサポートされている、if文やforループ、whileループをサポートしています。

if-then-else

void main() {
     // 値を`2`や`-1`に変更にして動作を確認する。
    int val = 3;
    if (val == 1) {
        print("この数値は1です。");
    }else if (val > 1) {
        print("この数値は1より大きいです");
    }else{
        print("この数値は1より小さいです。");
    }
}

while-loops

void main() {
  int count = 0;
  while(count < 10) {
    print("$count");
    count++;
  }
}

for-loop

void main() {
  for (var i=0; i<10; i++){
    print(i);
  }
  
  var list = [0,1,2,3,4,5];
  for (var i in list) {
    print(i);
  }
  
  var strList = ['a','b','c'];
  strList.forEach((var s){
    print(s);
  });
 }

クラスとメソッド(関数)

任意のclassを定義し、プロジェクト内で活用することができます。

void main() {
  Human me = Human("Yuuki", "Nishiyama", 32);
  
  String name = me.getName();
  print(name);
  
  me.doSelfIntroduction();
}

class Human {

  String firstName;
  String lastName;
  int age;

  Human(this.firstName, this.lastName, this.age);

  String getName(){
    return "$firstName $lastName";
  }
  
  void doSelfIntroduction(){
    String name = getName();
    print("Hello I'm $name. Please call me $firstName.");
  }
}

同期処理と非同期処理

同期処理では、重たい処理を実行すると、その処理が終了するまで待つ必要があります。 例えば、サーバから動画ファイルをダウンロードするような場合です。 処理が完了するまでの待ち時間に、別の処理を実行するためには、非同期処理という実装が必要です。 Dartでは、その非同期処理は非常に簡単に実装できます。

Ovenクラスは、引数1(Food)に対して引数2で指定した秒数の間、処理を行います。 12の処理は、同期処理なので、1が表示されてから3秒後に2が表示されると思います。 一方、345は非同期処理として実装されているので、3が表示された後に、5が表示され、3秒後に4が表示されます。このように、非常にシンプルに非同期処理を実装することができます。

void main() async {
  var potato = Food("Potato");
  var oven = Oven();
  
  /// 同期処理
  print("1. ${potato.name}");
  var food = await oven.bake(potato, 3);
  print("2. ${food.name}");
  
  /// 非同期処理
  var banana = Food("Banana");
  print("3. ${banana.name}");
  oven.bake(banana, 3).then((var food){
     print("4. ${food.name}");
  });
  print("5. ${banana.name}");
}

class Food {
  String name;
  Food(this.name);
}

class Oven{
  Future<Food> bake(Food food, int seconds) async {
    await Future.delayed(Duration(seconds: seconds));
    food.name = 'Baled ${food.name}';
    return food;
  }
}

非同期処理を実装する上で、asyncFuture<T>thenawaitを知る必要があります。 まず非同期で処理が実行される可能性があるメソッドには、メソッドの宣言の最後にasyncが宣言されています。

asyncは非同期で処理が進むことを意味して、戻り値としてFuture<T>を取ることが多いです。 Future<T>は、「非同期処理が完了した時に<>内の値が返ってきます」っという事を意味します。

非同期処理の完了をハンドルする複数ありますが、Future<T>thenメソッドと利用することで、処理完了時にコールバックを受け取ることができます。他には、非同期処理実行時にawaitを用いることで、非同期処理を同期処理のように実行することが可能です。

 Date: October 13, 2021
 Tags: 

Previous
⏪ 第3回:アプリ開発:UI(DartPadを用いた基礎練習)

Next
第1回:本講義の概要 ⏩