
Flutterを触り始めて次に立ちはだかるのが、Dartという言語の存在です。
Webエンジニア目線だと、「また新しい言語か…」という気持ちになりがちですが、結論から言うと、Flutterを書くためにDartを深く学ぶ必要はありません。
このSTEPでは、以下を目的にします。
「Dartという言語を理解する」ことではなく、
「Flutterを書く上で困らない最低限のDartを押さえる」
型システム(var / final / late / null safety)
Dartを最初に見て感じるのは、「JSっぽいけどJSじゃない」という違和感です。
その正体が、
型システムです。
var
var は一見JavaScriptの var に似ていますが、実際には型推論付きの変数宣言です。
一度代入された型は固定されるため、後から別の型を入れることはできません。
final
final は再代入不可の変数です。
PHPで言うところの定数に近いですが、実行時に値が決まる点が特徴です。
Flutterのコードでは頻繁に出てくるため、「迷ったら final」を基本ルールにすると混乱が減ります。
late
late は少し癖があります。
「後で必ず代入することを約束する」という宣言で、
null safetyを守りつつ初期化を遅らせたいときに使われます。
使いどころが分からないうちは、無理に使わなくても問題ありません。
null, safety
そして最大の特徴が null safety です。
Dartでは、nullを許容するかどうかが型レベルで決まります。
この仕組みのおかげで、
「実行してみたら null だった」
という事故が、かなり減ります。
最初は面倒に感じますが、
業務アプリを書く立場になると、この厳しさはむしろ味方になります。
クラス・コンストラクタ・mixin
Dartは、かなりオーソドックスな
オブジェクト指向言語です。
クラス、コンストラクタ、継承といった要素は、JavaやC#に近い印象があります。
Flutterでは、UIそのものがクラスとして表現されます。
そのため、クラス構文に慣れておくことは必須です。
コンストラクタはシンプルで、
引数をそのままプロパティに割り当てる書き方がよく使われます。
このあたりは、PHP8以降のコンストラクタプロパティに近い感覚です。
mixin
mixin というのは、最初は理解しなくても問題ありません。
「継承とは別に、機能を合成できる仕組みがある」くらいの認識で十分です。
このSTEPでは、
クラスが読めて、書けて、怖くなくなるそれだけを目標にします。
非同期処理(Future / async / await)
非同期処理については、JavaScript経験者であればほぼそのまま理解できます。
Future は Promise に近い存在で、async / await の書き方も非常によく似ています。
違いがあるとすれば、
非同期であることが型として明示される点です。
関数の戻り値に Future<T> が書かれていることで、「これは非同期だ」ということがコード上で一目で分かります。
Flutterでは、API通信や初期化処理で非同期処理が頻出します。
ここで迷わないためにも、「Future = Promise」という対応関係を頭に入れておくとスムーズです。
JS・PHPとの思考差分整理
Dartを触っていて一番大事なのは、「Dartらしく書こう」と思いすぎないことです。
JavaScriptの柔軟さや、PHPの雑さに慣れていると、Dartの厳密さは少し
窮屈に感じます。
ただし、Flutterにおいては、この厳密さが
UIの安定性や保守性につながっています。
Dartは、「フロントエンドだけど、バックエンド寄りの安全設計」という立ち位置の言語だと捉えると理解しやすくなります。
成果物:Dartだけで書いた小さなCLIロジック
このSTEPの最後にやるべきことは、
Flutterを書かないことです。
Dartだけで、小さなCLIロジックを書いてみます。
例えば、
・引数を受け取って処理する
・非同期で待つ
・クラスを1つ使う
それだけで十分です。
この作業の目的は、「Dartで考える感覚」を一度、UIから切り離して体験することです。
ここを飛ばしていきなりWidgetを書き始めると、
FlutterとDartの違和感が混ざって、理解が遅くなります。
Dart CLI
import 'dart:io';
Future<void> main(List<String> arguments) async {
final userName = arguments.isNotEmpty ? arguments[0] : 'Guest';
final service = UserService();
final message = await service.buildWelcomeMessage(userName);
stdout.writeln(message);
}
class UserService {
Future<String> buildWelcomeMessage(String name) async {
final normalizedName = _normalizeName(name);
await _simulateApiCall();
return 'Welcome, $normalizedName!';
}
String _normalizeName(String name) {
return name.trim().isEmpty ? 'Guest' : name;
}
Future<void> _simulateApiCall() async {
await Future.delayed(const Duration(seconds: 1));
}
}
実行
dart run main.dart Taro
> Welcome, Taro!
モックのポイント
・final が基本になる理由が分かる
・null safety を意識せずに書ける設計
・Future<void> が型として明示される安心感
・非同期処理が「見た目で分かる」
・クラスの責務が自然に分離される
このSTEPのまとめ
このSTEPで目指すゴールは、Dartを好きになることではありません。
読める
怖くない
書いても致命的に壊れない
この状態になれば十分です。
次のSTEPから、いよいよFlutterの本体であるWidgetの世界に入ります。
このステップのあとがき
型と非同期についての前提知識を頭に入れておくだけで、「Dartは大体理解できた」と考えていいのかな?と不安になるかもしれませんが、
具体的な書き方などは、サンプルを見てみると、Javascriptに非常に似ているな〜と思いました。
いっそのこと、何故Javascript(またはTypeScript)を採用しなかったのか・・・
と、いささか疑問に思いましたが、言語やプラットフォームの開発者に対して、文句を言っても始まらないので、「これはコレ」精神で、乗り切りたいと思います。
0 件のコメント:
コメントを投稿