下記の途中で併行して学習する必要性を感じ始めました。
内容を全部網羅できるといいとは思うのですが、そこまで時間を作るのが自分は上手くないのでまず上記のIntro to Dartを読み進めるのに最低限必要な文だけなぞっていきます。
①Dartの変数の宣言方法
以下のようなものがあるらしい
| 変数の宣言方法 | 特徴 | 下にいくほど縛りがきつい |
|---|---|---|
| dynamic | ・変数名の前につけると、どんな型のデータでも格納できる ・最初に代入した値と異なる型の値を再代入できる |
|
| var | 変数名の前につけることで型推論(型の記述を省略しても代入する値などから型を推論してくれる機能)が行われて、具体的な型の記述を省略できる | |
| final | ・変更不可(=再代入不可)(immutable)の変数を宣言する際に、変数名の前につける ・varやdynamicで定義した変数をこれで定義した変数に代入してもエラーにならない |
|
| const | ・変更不可(=再代入不可)(immutable)の変数を宣言する際に、変数名の前につける ・varやdynamicで定義した変数をこれで定義した変数に代入するとコンパイルエラーになる |
②変数宣言名の後ろに時々ある「?」が表すものはNull安全性
結局こういうことらしいです。
String? name // Nullもとりうる
String name // Nullは取りえない
ここに載ってました(Null Safety)
Google翻訳してちょっと修正したもの
Null安全性
Dartは、null安全性を確実なものとしています。
null安全性は、nullに設定された変数への意図しないアクセスによって発生するエラーを防ぐためのものです。このエラーはnull参照エラーと呼ばれます。null参照エラーは、nullと評価される式に対してプロパティにアクセスしたり、メソッドを呼び出したりした場合に発生します。このルールの例外は、toString()やhashCodeのように、プロパティまたはメソッドがnullをサポートしている場合です。null安全性により、Dartコンパイラはコンパイル時にこれらの潜在的なエラーを検出します。
例えば、int型変数iの絶対値を求めたいとします。iがnullの場合、i.abs()を呼び出すとnull参照エラーが発生します。他の言語では、これを実行しようとすると実行時エラーが発生する可能性があります。Dartのコンパイラは、これらの操作を禁止することで、このエラーを回避します。
Null 安全性により、次の 3 つの重要な変更が導入されます。
(1)変数、パラメータ、またはその他の関連コンポーネントの型を指定する際に、その型がnullを許容するかどうかを制御できます。null許容を有効にするには、型宣言の末尾に? を追加します。
(2)変数は使用する前に初期化する必要があります。null許容変数はデフォルトでnullとなるため、デフォルトで初期化されます。Dartはnull非許容型に初期値を設定しません。初期値の設定が強制されます。Dartでは、初期化されていない変数を参照することはできません。そのため、レシーバーの型がnullになる可能性があるにもかかわらず、nullがメソッドやプロパティをサポートしていないようなプロパティにアクセスしたり、メソッドを呼び出したりすることはできません。
(3)null許容型の式では、プロパティにアクセスしたりメソッドを呼び出したりすることはできません。hashCodeやtoString()など、nullがサポートするプロパティやメソッドの場合も、同様の例外が適用されます。
なお、Flutterに限らず、Null安全性が設定されているというのは極々ある話らしいです。
③「Dartにおけるthis」≒「Javaにおけるthis」(インスタンス自身を指す)
全部はまだ咀嚼できていないが、この人の説明が分かりやすかったです。
これに従うと例えば、冒頭のQiitaで取り上げた
class Package {
final String name;
final String latestVersion;
final String? description;
Package(this.name, this.latestVersion, {this.description});
@override
String toString() {
return 'Package{name: $name, latestVersion: $latestVersion, description: $description}';
}
}
の
Package(this.name, this.latestVersion, {this.description});
という部分は、このPackageクラスのインスタンスが(なんかくどいが)name、latestVersion、descriptionという3つの変数をもつということらしいです。
※descriptionには {this.description}というように中括弧{}がついているが、これは「任意」(=省力可能)という意味らしいです。
④toString()は変数から文字列型のオブジェクトを生み出すメソッド
※Dartでは、すべてのクラスは暗に Object を継承しており、toString() メソッドを持っている(⇒クラス内でtoString()メソッドを使用できる)
上記の
String toString() {
return 'Package{name: $name, latestVersion: $latestVersion, description: $description}';
}
というのはname、latestVersion、descriptionという3つの変数を受けて、最終的に
「Pacakage{name: 〇〇〇, latestVersion: △△△, description: ~~~}」という文字列を返り値を返すことを意味しているらしいです。
上記の③と④の内容をまとめると・・・
上記のコードは、Packageというクラスは、「name、latestVersion、descriptionという3つの変数を受けて、返り値として④に示したような文字列を返すインスタンスを生成時に生み出す」というものらしいです。
結果例えば、冒頭にあるFlutterのIntro to dartをややいじって簡単にした
class Package {
final String name;
final String latestVersion;
final String? description;
Package(this.name, this.latestVersion, {this.description});
@override
String toString() {
return 'Package{name: $name, latestVersion: $latestVersion, description: $description}';
}
}
void main(){
var name = "Python";
var latestVersion = '3';
var description = "テスト";
final p = Package(name, latestVersion, description: description);
print(p);
}
というコードをDartpadで試すと、
Package{name: Python, latestVersion: 3, description: テスト}
という結果が得られました。
主な参考資料
①Flutterで始めるはじめてのモバイルアプリ開発 Tamappe (著) 技術評論社
②【Flutter/Dart】Dartの文法について学ぼう @my_programming(Python Lover) さんQiita
https://qiita.com/my_programming/items/9ba25114ef217d077ca5
③【Dart】Objectクラスの基本 @iwaku8 さん Zenn
https://zenn.dev/iwaku/articles/2020-12-18-iwaku