1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Flutter入門 第1回】Dart の基本 ― 変数・型・演算子を完全理解する

1
Posted at

はじめに

Flutter でアプリを開発するには、まず Dart というプログラミング言語を理解する必要があります。

このシリーズでは、Flutter 開発に必要な Dart の文法を基礎から丁寧に解説していきます。第1回は 変数・型・演算子 です。

Dart とは?

Dart は Google が開発したプログラミング言語です。Flutter のアプリケーションはすべて Dart で記述します。

  • Google が 2011 年に発表
  • Flutter の公式言語
  • 型安全でありながら、型推論も備える
  • コンパイル言語(AOT/JIT 両対応)

DartPad で手軽に試そう

Dart のコードはブラウザ上の DartPad で即座に実行できます。環境構築は不要です。

https://dartpad.dev

本記事のコード例はすべて DartPad にコピー&ペーストして実行できます。


1. 変数宣言

var による宣言

var を使うと、代入した値から型が自動的に推論されます。

void main() {
  var name = 'Taro';    // String と推論される
  var age = 25;          // int と推論される
  var height = 170.5;    // double と推論される
  var isStudent = true;  // bool と推論される

  print(name);      // Taro
  print(age);        // 25
  print(height);     // 170.5
  print(isStudent);  // true
}

var で宣言した変数は、推論された型と異なる型の値を再代入できません。

void main() {
  var count = 10;  // int と推論される
  count = 20;      // OK(同じ int 型)
  // count = 'hello';  // コンパイルエラー(String は代入できない)
  print(count); // 20
}

型を明示して宣言する

型を直接指定することもできます。コードの意図が明確になるため、実務では型を明示するスタイルも多く使われます。

void main() {
  String name = 'Taro';
  int age = 25;
  double height = 170.5;
  bool isStudent = true;

  print('$name$age 歳、身長 $height cm');
  // Taro は 25 歳、身長 170.5 cm
}

dynamic 型

dynamic を使うと、任意の型の値を代入できます。型チェックが行われないため、ランタイムエラーの原因になりやすく、通常は使用を避けます。

void main() {
  dynamic value = 'Hello';
  print(value);        // Hello
  print(value.runtimeType); // String

  value = 42;
  print(value);        // 42
  print(value.runtimeType); // int

  value = true;
  print(value);        // true
  print(value.runtimeType); // bool
}

2. final と const

final ― 実行時に一度だけ代入

final で宣言した変数には一度だけ値を代入でき、その後は変更できません。値は 実行時 に決まります。

void main() {
  final String greeting = 'Hello, Dart!';
  // greeting = 'Hi!';  // コンパイルエラー(再代入不可)
  print(greeting); // Hello, Dart!

  // 型推論との併用も可能
  final now = DateTime.now(); // 実行時の現在時刻が入る
  print(now);
}

const ― コンパイル時定数

constコンパイル時に値が確定する 定数です。実行時に決まる値(DateTime.now() など)は代入できません。

void main() {
  const double pi = 3.14159265358979;
  const int maxRetry = 3;

  print(pi);       // 3.14159265358979
  print(maxRetry);  // 3

  // const now = DateTime.now();  // コンパイルエラー(実行時の値は不可)
}

final と const の違いまとめ

特徴 final const
再代入 不可 不可
値の決定タイミング 実行時 コンパイル時
DateTime.now() 使用可能 使用不可
インスタンス変数 使用可能 使用不可(static const は可)

3. 数値型: int, double, num

Dart の数値型は int(整数)と double(浮動小数点数)の2つです。num はその親クラスで、整数と小数の両方を受け取れます。

void main() {
  int count = 42;
  double price = 19.99;
  num value = 100;    // int でも double でも代入可能

  print(count);  // 42
  print(price);  // 19.99
  print(value);  // 100

  value = 3.14;  // double も代入可能
  print(value);  // 3.14
}

int と double の変換

void main() {
  int a = 10;
  double b = a.toDouble();
  print(b); // 10.0

  double c = 3.7;
  int d = c.toInt(); // 小数部分を切り捨て
  print(d); // 3

  int e = c.round(); // 四捨五入
  print(e); // 4
}

4. 文字列型: String

シングルクォートとダブルクォート

Dart ではどちらも使えます。Dart の公式スタイルガイド(Effective Dart)ではシングルクォートが推奨されています。

void main() {
  String single = 'Hello';
  String double_ = "World";

  print(single); // Hello
  print(double_); // World
}

文字列補間

$variable で変数を、${expression} で式を文字列中に埋め込めます。

void main() {
  String name = 'Taro';
  int age = 25;

  // $ で変数を埋め込む
  print('名前: $name');        // 名前: Taro

  // ${} で式を埋め込む
  print('来年は ${age + 1} 歳'); // 来年は 26 歳

  // 文字列の長さ
  print('名前の文字数: ${name.length}'); // 名前の文字数: 4
}

複数行文字列

トリプルクォート(''' または """)を使うと、複数行の文字列を記述できます。

void main() {
  String multiLine = '''
1行目
2行目
3行目
''';
  print(multiLine);
  // 1行目
  // 2行目
  // 3行目
}

文字列の結合

+ 演算子またはリテラルの隣接で結合できます。

void main() {
  String first = 'Hello';
  String second = 'World';

  // + で結合
  print(first + ', ' + second + '!'); // Hello, World!

  // リテラルの隣接(変数には使えない)
  print('Hello, '
      'World!'); // Hello, World!
}

5. bool 型

true または false のどちらかの値を取ります。Dart は 厳密な bool 型 を要求し、JavaScript のような暗黙の型変換は行いません。

void main() {
  bool isActive = true;
  bool isDeleted = false;

  print(isActive);   // true
  print(isDeleted);  // false

  // if 文には bool 型のみ使用可能
  // if (1) {}    // コンパイルエラー(int は bool ではない)
  // if ('') {}   // コンパイルエラー(String は bool ではない)

  if (isActive) {
    print('アクティブです'); // アクティブです
  }
}

6. 算術演算子

void main() {
  int a = 17;
  int b = 5;

  print('$a + $b = ${a + b}');   // 17 + 5 = 22
  print('$a - $b = ${a - b}');   // 17 - 5 = 12
  print('$a * $b = ${a * b}');   // 17 * 5 = 85
  print('$a / $b = ${a / b}');   // 17 / 5 = 3.4(常に double を返す)
  print('$a ~/ $b = ${a ~/ b}'); // 17 ~/ 5 = 3(整数除算)
  print('$a % $b = ${a % b}');   // 17 % 5 = 2(剰余)
}
演算子 意味 結果
+ 加算 17 + 5 22
- 減算 17 - 5 12
* 乗算 17 * 5 85
/ 除算(double を返す) 17 / 5 3.4
~/ 整数除算 17 ~/ 5 3
% 剰余 17 % 5 2

注意: Dart の / は常に double を返します。整数の商が欲しい場合は ~/ を使います。これは Java や Python とは異なる Dart 独自の演算子です。


7. 比較演算子

void main() {
  int x = 10;
  int y = 20;

  print('$x == $y${x == y}');   // 10 == 20 → false
  print('$x != $y${x != y}');   // 10 != 20 → true
  print('$x > $y${x > y}');     // 10 > 20 → false
  print('$x < $y${x < y}');     // 10 < 20 → true
  print('$x >= 10 → ${x >= 10}');  // 10 >= 10 → true
  print('$x <= $y${x <= y}');   // 10 <= 20 → true
}

8. 論理演算子

void main() {
  bool a = true;
  bool b = false;

  print('$a && $b${a && b}');   // true && false → false
  print('$a || $b${a || b}');   // true || false → true
  print('!$a${!a}');            // !true → false
  print('!$b${!b}');            // !false → true

  // 実用例
  int age = 25;
  bool hasLicense = true;

  if (age >= 18 && hasLicense) {
    print('運転できます');  // 運転できます
  }
}
演算子 意味 説明
&& 論理AND 両方 true のとき true
|| 論理OR どちらか一方が true のとき true
! 論理NOT truefalse を反転

9. 代入演算子

void main() {
  int score = 100;
  print('初期値: $score');  // 初期値: 100

  score += 20;
  print('+= 20 → $score');  // += 20 → 120

  score -= 30;
  print('-= 30 → $score');  // -= 30 → 90

  score *= 2;
  print('*= 2 → $score');   // *= 2 → 180

  score ~/= 3;               // Dart の整数除算代入は ~/=
  print('~/= 3 → $score');  // ~/= 3 → 60

  score %= 7;
  print('%= 7 → $score');   // %= 7 → 4
}

??= 演算子(null の場合のみ代入)

??= は、変数が null のときだけ値を代入します。

void main() {
  String? name;       // null で初期化される
  print(name);        // null

  name ??= 'デフォルト名';
  print(name);        // デフォルト名

  name ??= '別の名前'; // すでに null ではないので代入されない
  print(name);        // デフォルト名
}

10. 型チェック: is / is!

is で型チェック、is! で「その型ではない」ことを確認できます。

void main() {
  dynamic value = 42;

  print(value is int);      // true
  print(value is double);   // false(※ DartPad では true。後述の注意を参照)
  print(value is! String);  // true

  value = 'Hello';
  print(value is String);   // true
  print(value is int);      // false
}

注意: DartPad は JavaScript にコンパイルして実行するため、JavaScript の仕様上 42 is doubletrue になります。ネイティブ環境(dart run など)では false です。整数リテラルは int 型ですが、Web 環境では内部的に全て浮動小数点数として扱われるためです。

is による型チェックの後、Dart は自動的に型を絞り込みます(スマートキャスト)。

void main() {
  Object obj = 'Hello, Dart!';

  if (obj is String) {
    // このブロック内では obj は String として扱える
    print(obj.toUpperCase()); // HELLO, DART!
    print(obj.length);        // 12
  }
}

11. 総合的なコード例

ここまでの内容を使った実践的な例を示します。

void main() {
  // 商品情報
  const String productName = 'Dart入門書';
  const int basePrice = 2800;
  const double taxRate = 0.10;

  // 税込価格を計算
  final int tax = (basePrice * taxRate).toInt();
  final int totalPrice = basePrice + tax;

  // 結果を表示
  print('=== 商品情報 ===');
  print('商品名: $productName');
  print('税抜価格: $basePrice 円');
  print('消費税(${(taxRate * 100).toInt()}%): $tax 円');
  print('税込価格: $totalPrice 円');
  // === 商品情報 ===
  // 商品名: Dart入門書
  // 税抜価格: 2800 円
  // 消費税(10%): 280 円
  // 税込価格: 3080 円

  // 型の確認
  print('\n=== 型の確認 ===');
  print('productName is String: ${productName is String}'); // true
  print('basePrice is int: ${basePrice is int}');           // true
  print('taxRate is double: ${taxRate is double}');          // true
}

練習問題

練習問題 1: 自己紹介プログラム

以下の変数を宣言し、文字列補間を使って自己紹介文を出力してください。

  • 名前(String): "山田花子"
  • 年齢(int): 28
  • 趣味(String): "読書"
  • プログラミング歴(double): 1.5(年)

期待する出力:

こんにちは、山田花子です!
年齢は28歳で、趣味は読書です。
プログラミング歴は1.5年です。来年は2.5年になります。
模範解答
void main() {
  String name = '山田花子';
  int age = 28;
  String hobby = '読書';
  double programmingYears = 1.5;

  print('こんにちは、${name}です!');
  print('年齢は${age}歳で、趣味は${hobby}です。');
  print('プログラミング歴は${programmingYears}年です。来年は${programmingYears + 1}年になります。');
}

ポイント: $variable は単純な変数の埋め込みに、${expression} は式の埋め込みに使います。programmingYears + 1 は式なので ${} を使います。


練習問題 2: 円の面積と円周の計算

半径 7 の円の面積と円周を計算してください。円周率は const3.14159265358979 と定義してください。

  • 面積 = 円周率 x 半径 x 半径
  • 円周 = 2 x 円周率 x 半径

期待する出力:

半径: 7
面積: 153.93804002589985
円周: 43.982297150257104
模範解答
void main() {
  const double pi = 3.14159265358979;
  int radius = 7;

  double area = pi * radius * radius;
  double circumference = 2 * pi * radius;

  print('半径: $radius');
  print('面積: $area');
  print('円周: $circumference');
}

ポイント:

  • pi * radius * radius の計算では、intdouble の乗算結果は自動的に double になります。
  • 面積: 3.14159265358979 * 7 * 7 = 3.14159265358979 * 49 = 153.93804002589985
  • 円周: 2 * 3.14159265358979 * 7 = 43.982297150257104

練習問題 3: 型の判定プログラム

dynamic 型の変数に順番に異なる型の値を代入し、is 演算子で型を判定して結果を出力してください。

以下の値を順番に判定してください: 42, 3.14, 'Dart', true

期待する出力:

値: 42 → int: true, double: false, String: false, bool: false  ※ DartPad では double: true
値: 3.14 → int: false, double: true, String: false, bool: false
値: Dart → int: false, double: false, String: true, bool: false
値: true → int: false, double: false, String: false, bool: true
模範解答
void main() {
  dynamic value;

  value = 42;
  print('値: $value → int: ${value is int}, double: ${value is double}, String: ${value is String}, bool: ${value is bool}');

  value = 3.14;
  print('値: $value → int: ${value is int}, double: ${value is double}, String: ${value is String}, bool: ${value is bool}');

  value = 'Dart';
  print('値: $value → int: ${value is int}, double: ${value is double}, String: ${value is String}, bool: ${value is bool}');

  value = true;
  print('値: $value → int: ${value is int}, double: ${value is double}, String: ${value is String}, bool: ${value is bool}');
}

ポイント: is 演算子はランタイムの型を判定します。dynamic 型の変数でも、実際に格納されている値の型に基づいて正確に判定されます。


まとめ

項目 内容
変数宣言 var(型推論)、型を明示、dynamic(非推奨)
再代入不可 final(実行時)、const(コンパイル時)
数値型 intdoublenum(親クラス)
文字列 シングル/ダブルクォート、$/${}補間、'''複数行
bool true/false(暗黙変換なし)
算術演算子 +, -, *, /(double), ~/(整数除算), %
比較演算子 ==, !=, >, <, >=, <=
論理演算子 &&, ||, !
代入演算子 =, +=, -=, *=, /=, ??=
型チェック is, is!(スマートキャスト付き)

次回(第2回)は 制御構文(if / for / while / switch) を学びます。


参考


@kotaro_ai_lab
AI活用や開発効率化について発信しています。フォローお気軽にどうぞ!

1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?