Open8
[Flutter] dart言語仕様
遅延初期化 (late)
- late修飾子は、宣言時に初期化処理を記述すると、変数にアクセスされるまで初期化処理を遅延することができる
- 使用されるかどうかわからない変数や、初期化処理の実行コストが高い場合に用いると効果的
- 未初期化の変数にアクセスすると実行時エラーになるので注意が必要
型
List(配列) -順序付きコレクション-
// 初期化処理
final list1 = [0,1,2,3];
final list2 = <int>[0,1,2,3];
// list3をもとに固定長の新しいインスタンスを生成
final list3 = [0,1,2,3];
final fixedLengthList = List.unmodifiable(list3);
fixedLengthList.add(4); // 実行時エラー
Set(集合) -順序が保持されず、重複しないコレクション-
// 初期化処理
final map1 = { 'Apple', 'Orange', 'Grape' };
final map2 = <String>{ 'Apple', 'Orange', 'Grape' };
final fruits = { 'Apple', 'Orange', 'Grape' };
fruits.add('Cherry');
fruits.add(123); // エラー
Map(連想配列) -辞書型-
// 初期化処理
final map1 = {
200: 'OK',
403: 'access forbidden',
404: 'not found'
};
final map2 = <int,String>{
200: 'OK',
403: 'access forbidden',
404: 'not found'
};
map2[204] = 'No Content';
Record(タプル) -複数の値を集約した匿名型-
final record1 = (300, 'cake');
final (int, String) record2 = record1;
// 型注釈では名前付きフィールドを中括弧で囲う
final record3 = (price: 300, name: 'cake');
final ({int price, String name}) record4 = (price: 300, name: 'cake');
三項演算子
条件式 ? 式1 : 式2
int a = 128;
int b = 256;
final max = a > b ? a : b;
print(max);
カスケード記法
- カスケード記法は同じオブジェクトに対して、繰り返し操作を行う時に便利な記述方法
final sb = StringBuffer()
..write('Hello)
..write(' , ')
..write('Dart!');
// => Hello, Dart!
ループ
for文
final list = [0,1,2];
for(final element in list){
print('element = $element');
}
// => elment = 0
// => elment = 1
// => elment = 2
forEachメソッド
final list = [0,1,2];
list.forEach(elment){
print('element = $element');
}
// => elment = 0
// => elment = 1
// => elment = 2
クラス
コンストラクタ
xとyの初期値をコンストラクタから与える方法
class Point{
Point(int xPosition, int yPosition) : x = xPosition, y = yPosition;
int x;
int y;
}
コンストラクタ引数を直接初期値として与える方法
class Point{
Point(this.x, this.y);
int x;
int y;
}
constantコンストラクタ
- クラスインスタンスをコンパイル時定数として扱うにはconstantコンストラクタが必要
- コンストラクタにconstキーワードを付与する
- インスタンス変数は全て再代入不可なfinalである必要がある
- 無駄なインスタンス生成を避けることができるため、パフォーマンス向上に役立つ
class Point{
const Point(this.x, this.y);
final int x;
final int y;
final point1 = const Point(1, 2);
const point2 = Point(1, 2);
final point3 = Point(1, 2);
print('${point1 == point2}'); // point1とpoint2は同じインスタンス
// => true
print('${point1 == point3}');
// => false
名前付きコンストラクタ
class Point{
const Point(this.x, this.y);
const Point.zero() : x = 0, y = 0; //名前付きコンストラクタ
final int x;
final int y;
factoryコンスタラクタ
必ずしも新しいインスタンスを生成しない場合に利用する
class UseData{
static final Map<int, UserData> _cache = {};
factory UserData.fromCache(int userId){
final cache = _chche[userId];
if(cache != null){
return cache;
}
final newInstance = UserData();
_cache[userId] = newInstance;
return newInstance;
}
}
クラス継承
スーパークラスのコンストラクタ
- サブクラスのコンストラクタでは、スーパークラスの引数のないコンストラクタが自動的に呼び出される
- スーパークラスに引数なしコンストラクタがない場合は、明示的にスーパークラスのコンストラクタを呼び出す必要がある
class Animal{
Animal(this.name);
final String name;
}
class Dog extends Animal{
Dog(String name) : super(name);
}
上の例のように、コンストラクタ引数をそのままスーパークラスのコンストラクタに渡す記述は糖衣構文が用意されている
class Animal{
Animal(this.name);
final String name;
}
class Dog extends Animal{
Dog(super.name);
}
非同期処理
Future型
Futureのthenメソッドには処理が完了した時に呼び出されるコールバックを渡す
import 'dart:io';
void main(){
Future<String> ccontent = File('file.txt').readAsString();
content.then((content){
print(conten);
});
}
Futureクラスはasync,awaitキーワードと組み合わせることで、動機的なコードのように記述できる
import 'dart:io';
Future<void> main() async{
String content = await File('file.txt').readAsString();
print(content);
}
エラーハンドリング
catchErrorメソッドで例外が発生した時に呼び出されるコールバックを登録する
Future<String> fetchUserName(){
var str = Future.delayed(
const Duration(seconds:1),
() => throw 'User not found.');
return str;
}
fetchUserName()
.then((name){
print ('User name is $name');
})
.catchError(e){
print(e);
});
// => User not found.
async-awaitで実行した非同期処理はtry-catch構文で例外を捕捉する
Future<String> fetchUserName(){
var str = Future.delayed(
const Duration(seconds:1),
() => throw 'User not found. ');
return str;
}
try{
final name = await fetchUserName();
print ('User name = $name');
}catch(e){
print(e);
}
// => User not found.