[Flutter] Dartの変数

2023-03-18 hit count image

Flutterでアプリを開発するためFlutterの開発言語であるDartについて説明します。今回のブログポストではDartの変数について説明します。

ブログシリーズ

このブログはシリーズで作成しております。下記のリンクを参考して他のブログポストも確認してみてください。

概要

Flutterはグーグルで開発したDartと言う言語を使って開発します。

このブログポストではFlutterで使ってるDart言語の基本的な使い方を説明して、Dartの変数について詳しく説明します。

このブログポストで紹介するソースコードは下記のリンクで確認できます。

開発環境

Dartをローカルで開発するためにはFlutterをインストールして設定する必要があります。以前のブログポストを参考して開発環境を構築してください。

今回のブログポストではFlutterのインストールや設定はできた前提で進めます。そしたら、Dartの言語を使うため新しフォルダを生成します。

mkdir dart
cd dart

そして下記のコマンドw実行してVSCodeを実行します。

code .

Hello world

まず、Dartでコーディングするため、Dartファイルを生成してみましょう。VSCodeで下記のように新しファイルを生成してみます。

VSCode - create Dart file

ファイル名はなんでもいいですが、ここではmain.dartで生成します。このようにファイルを生成したら、当該ファイルを開いて下記のように作成します。

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

全ての内容をセク生したら、cmd + shift + dを押して、Debug: restartを検索して実行します。

VSCode - Dart debugging

そしたらVSCodeが.vscode/launch.jsonファイルを自動生成してくれます。

VSCode - Dart launch.json

私たちはそのファイルで私たちのDartファイルを指定する必要があります。当該ファイルを開いて下記のように修正します。

{
  ...
  "configurations": [
    {
      ...,
      "program": "main.dart"
    }
  ]
}

このように修正したら、またmain.dartファイルに移動して、cmd + shift + dを押してdebug restartを再び実行します。そしたら下記のようにDEBUG CONSOLEに私たちが作成したHello worldが表示されることが確認できます。

VSCode - Dart Hello world

コードの詳しい説明は省略します。

変数

Dartで使える変数を説明します。

var

JavaScriptのvarと似てる動きをする変数です。どのタイプの変数も割り当てることができます。

void main() {
  var value1 = 'test';
  print(value1);

  var value2 = 1;
  print(value2);
}

宣言と同時に変数を割り当てた場合、Dartは変数のタイプを固定します。上の例ではvalue1Stringタイプになり、value2intタイプになります。

このようにタイプが固定された後、他のタイプを入れるとエラーが発生します。

VSCode - Dart wrong type error

しかし、宣言と同時に割り当てないと、どのタイプも入れることができるDynamic Typeの変数になります。

void main() {
  var value1;

  value1 = 'test';
  print(value1);

  value1 = 1;
  print(value1);
}

例題ではStringタイプを割り当てた後、またintタイプのデータを入れましたが、以前と違ってエラーが発生したいことが確認できます。

int

Dartで整数型のデータを扱う場合はintタイプを使います。

void main() {
  int num1 = 2;
  int num2 = 4;

  print(num1 + num2);
  print(num1 - num2);
  print(num1 * num2);
  print(num1 / num2);
}

intタイプで宣言した変数は基本的な数学演算ができます。

double

Dartでは実数型データを扱う時doubleタイプを使います。

void main() {
  double num1 = 2.2;
  double num2 = 4.2;

  print(num1 + num2);
  print(num1 - num2);
  print(num1 * num2);
  print(num1 / num2);
}

doubleタイプも基本的数学演算ができます。

String

Dartで文字列を扱う時はStringタイプを使います。ここで気をつけることがStringタイプはintdoubleと違って大文字(S)で始めます。

void main() {
  String name = 'Yakuza';

  print(name);
  print('Dev ' + name);
  print(name.toUpperCase());
  print(name.toLowerCase());
}

Stringタイプは他の言語と同じように+を使って結合することができますし、色んな関数を使うことができます。 기호를 통해 합칠 수 있습니다.

bool

Dartでもtrue/falseを保存することができるBooleanタイプを持ってます。

void main() {
  bool wrong = true;
  print(wrong);

  wrong = false;
  print(wrong);
}

List

Dartでは下記のようにリスト変数を宣言してデータを追加することができます。

void main() {
  List<String> fruits = [];

  fruits.add('Apple');
  fruits.add('Banana');
  fruits.add('Kiwi');

  print(fruits);
  fruits.removeAt(1);
  print(fruits);
}

または下記のように生成することもできます。

void main() {
  List<String> fruits = ['Apple', 'Banana', 'Kiwi'];
  print(fruits);
}

また下記のように使うこともできます。

void main() {
  List<String> fruits = List.from(['Apple', 'Banana', 'Kiwi']);
  print(fruits);
}

Listは上のように可変的なリストを作ることもできますが、下記のように固定サイズのリストも生成することもできます。

void main() {
  List<String> fruits = List.filled(3, '');

  fruits[0] = 'Apple';
  fruits[1] = 'Banana';
  fruits[2] = 'Kiwi';

  print(fruits);
}

ここで気をつけることは固定サイズのListaddremoveAtようにリストの長さを変える関数は使うことができないことです。

Listキーワードを使う時、可変なリストも作ることができます。下記のようにListを生成すると可変リストが生成されます。

void main() {
  List<String> fruits = List.empty(growable: true);

  fruits.add('Apple');
  fruits.add('Banana');
  fruits.add('Kiwi');

  print(fruits);
}

Listでは色んな関数を使うことができます。

  • join: 各要素を合わせて1つの文字列を生成します。

    void main() {
      List<String> fruits = ['Apple', 'Banana', 'Kiwi'];
      print(fruits.join(', '));
    }
    
  • indexOf: 要素を探して、その要素のindexを返します。

    void main() {
      List<String> fruits = ['Apple', 'Banana', 'Kiwi'];
      print(fruits.indexOf('Banana'));
    }
    
  • where: 条件に合う要素で新しいリストを作ります。

    void main() {
      List<String> fruits = ['Apple', 'Banana', 'Kiwi'];
      print(fruits.where((fruit) => fruit.toLowerCase().indexOf('a') >= 0));
    }
    
  • forEach: forループと同じ役割

    void main() {
      List<String> fruits = ['Apple', 'Banana', 'Kiwi'];
    
      fruits.forEach((fruit) {
        print('${fruit}!');
      });
    
      for (String fruit in fruits) {
        print('${fruit}!!');
      }
    }
    
  • map: forEachのようにループをしますが、ループ中の関数で返した値で新しリストを作成します。

    void main() {
      List<String> fruits = ['Apple', 'Banana', 'Kiwi'];
      Iterable<String> newFruits = fruits.map((e) {
        return 'My name is ${e}';
      });
      print(newFruits);
      print(newFruits.toList());
    }
    
  • fold: 初期値を持ってループをしながら、以前の値と現在値を持って新しい結果値を作る時、使います。

    void main() {
      List<int> numbers = [1, 2, 3, 4, 5];
      int result = numbers.fold(0, (previousValue, element) {
        int sum = previousValue + element;
        return sum * 2;
      });
      print(result);
    }
    
  • reduce: foldとは違って初期値がないです。必ず要素と同じタイプを返さなきゃならないです。

    void main() {
      List<int> numbers = [1, 2, 3, 4, 5];
      int total = numbers.reduce((value, element) => value + element);
      print(total);
    }
    
  • asMap: ListタイプをMapタイプに変更します。この時生成されたMapはListのindexをキーとして使って生成されます。indexの値が必要な時、よく使えます

    void main() {
      List<int> numbers = [10, 20, 30, 40, 50];
      Iterable indexNumbers = numbers.asMap().entries.map((e) {
        return 'index: ${e.key} / value: ${e.value}';
      });
      print(indexNumbers);
      print(indexNumbers.toList());
    }
    

Map

MapListと同じように複数の変数を保存することができますが、Listと違ってKey Valueでデータを保存します。MapはKey-Valueで値を保存するので、Keyはユニークです。

void main() {
  Map fruitCount = {
    'Apple': 3,
    'Banana': 4,
    'Kiwi': 10,
  };

  print(fruitCount);
  print(fruitCount['Apple']);
}

MapもListと同じように変数を宣言し後、データを追加、削除、変更することができます。

void main() {
  Map fruitCount = {};

  fruitCount.addAll({
    'Apple': 3,
    'Banana': 4,
    'Kiwi': 10,
  });

  print(fruitCount);
  fruitCount.remove('Apple');
  print(fruitCount);
  fruitCount['Banana'] = 20;
  print(fruitCount);
}

Mapは次のように使うこともできます。

void main() {
  Map fruitCount = new Map.from({
    'Apple': 3,
    'Banana': 4,
    'Kiwi': 10,
  });

  print(fruitCount);
}

Mapは色んな機能も提供してます。例えば次のようにMapのKeyとValueをまとめて出力することができます。

void main() {
  Map fruitCount = new Map.from({
    'Apple': 3,
    'Banana': 4,
    'Kiwi': 10,
  });

  print(fruitCount.keys.toList());
  print(fruitCount.values.toList());
}

MapもListようにタイプを設定することができます。

void main() {
  Map<String, int> fruitCount = {
    'Apple': 3,
    'Banana': 4,
    'Kiwi': 10,
  };

  print(fruitCount);
}

Mapにはentriesを使ってループすることができて、結果で新しいリストを作ることができます。

void main() {
  Map<String, int> fruitCount = {
    'Apple': 3,
    'Banana': 4,
    'Kiwi': 10,
  };

  Iterable newFruitCount =
      fruitCount.entries.map((e) => '${e.key} is ${e.value}!');
  print(newFruitCount);
  print(newFruitCount.toList());
}

enum

Dartでは下記のようにenumを使うことができます。

enum Status {
  wait,
  approved,
  reject,
}

void main() {
  Status currentStatus = Status.wait;
  print(currentStatus == Status.approved);
  print(Status.values.toList());
}

定数

Dartで定数を使う方法について説明します。

finalとconst

Dartではfinalconstを使って定数を宣言することができます。

void main() {
  final String firstName = 'Yakuza';
  const String lastName = 'Dev';
  print(firstName);
  print(lastName);
}

定数で宣言した変数は変更ができません。

void main() {
  final String name = 'Yakuza';
  name = 'Dev'; << ERROR
  print(name);
}

finalconstは下記のような違さがあります。

  • final: ランタイムで定数が指定される
  • const: コンパイル時点で定数が指定される。
void main() {
  final DateTime now = DateTime.now();
  print(now);
}

例えば、次のようにDateTimeを使って現在時間を定数で作ってみました。しかし現在時間はランタイムの時、分かるので、次のようにconstで定数を指定するとエラーが発生します。

void main() {
  const DateTime now = DateTime.now();
  print(now);
}

現在時間はプログラムを実装してみないと分からないので、コンパイルの時点では指定できません。

String Interpolation

Dartでは下記のように文字列に変数を入れって出力することができます。

void main() {
  String name = 'Yakuza';
  int num = 1;

  print('User: (${num}) ${name}');
}

この例題を実行すると下記のような結果が表示されます。

User: (1) Yakuza

Nullable

今までみた変数は全て初期値を入れてました。初期値を入れないとエラーが発生します。しかしDartでは下記のように初期値を入れなく変数を宣言することもできます。

void main() {
  String? name;
  name = 'Yakuza';
  print(name);

  name = null;
  print(name);
}

上のように?を使って、初期値を設定しなくて変数を宣言することができるし、このように宣言した変数は初期値でnullを持ってます。また、nullを入れることもできます。

変数の特徴

変数は次のような特徴を持ってます。

  • 同じ変数名で重複宣言ができない。

      void main() {
        String name = 'Yakuza';
        String name = 'Dev';
        int name = 1;
      }
    
  • 変数名は小文字で始まり、キャメルケース(Camelcase)で作ります。
  • 変数の名前は_で始まることが出来ますが、この変数はクラスのprivate変数名で使えます。
  • クラスは大文字で始めます。だから、変数の名前を大文字で宣言する場合、クラスと変数を区分することが難しくなります。

完了

これでFlutterでアプリを開発するためDartの変数についてみてみました。私たちはDartで自由に変数と定数を宣言することができるようになりました!

私のブログが役に立ちましたか?下にコメントを残してください。それは私にとって大きな大きな力になります!

アプリ広報

今見てるブログを作成たDekuが開発したアプリを使ってみてください。
Dekuが開発したアプリはFlutterで開発されています。

興味がある方はアプリをダウンロードしてアプリを使ってくれると本当に助かります。

Posts