Closed7
DartのNull safety codelabやってみる
Non-nullable typesにはnullを代入できない
void main() {
int a;
a = null; // Null can't be assigined
print('a is $a.');
}
Nullable types
-
?
をつける
void main() {
int? a;
a = null;
print('a is $a.'); // a is null
}
Nullable type parameters for generics
void main() {
List<String> aListOfStrings = ['one', 'two', 'three'];
List<String>? aNullableListOfStrings;
List<String?> aListOfNullableStrings = ['one', null, 'three'];
print('aListOfStrings is $aListOfStrings.');
print('aNullableListOfStrings is $aNullableListOfStrings.');
print('aListOfNullableStrings is $aListOfNullableStrings.');
}
The null assertion operator (!)
- nullable typeがnullでないことを表現したいときは
!
を使う
int? couldReturnNullButDoesnt() => -3;
void main() {
int? couldBeNullButIsnt = 1;
List<int?> listThatCouldHoldNulls = [2, null, 4];
int a = couldBeNullButIsnt;
int b = listThatCouldHoldNulls.first!; // first item in the list
int c = couldReturnNullButDoesnt()!.abs(); // absolute value
print('a is $a.');
print('b is $b.');
print('c is $c.');
}
Type promotion
-
Nullになる可能性がある変数でも、nullにならないのであれば、non-nullableな変数として扱う
-
Definite assignment
Dartでは、変数がどこで割り当てられ読み込まれたかを追跡することができ、コードが読み込もうとする前にのnon-nullableな変数に値が代入されているかを検証することができる。これをdefinite assignmentと呼ぶ
void main() {
String text;
// 以下のif文をコメントアウトすると、エラーになる
if (DateTime.now().hour < 12) {
text = "It's morning! Let's make aloo paratha!";
} else {
text = "It's afternoon! Let's make biryani!";
}
print(text);
print(text.length);
}
late
キーワード
クラス変数やトップレベル変数?はnon-nullableであるべきだが、値をすぐには代入できない場合がある。
そういうときにはlate
を使う。late
を使うことで、
- あとで代入することを宣言できる。non-nullableな型で代入してなくてもエラーにならない
- 代入されずに値が使用されると
LateInitializationError
を投げる -
late
はfinal
と一緒に使うこともできる
class Meal {
late String _description;
set description(String desc) {
_description = 'Meal description: $desc';
}
String get description => _description;
}
void main() {
final myMeal = Meal();
myMeal.description = 'Feijoada!';
print(myMeal.description);
}
final
と使う
class Team {
late final Coach coach;
}
class Coach {
late final Team team;
}
void main() {
final myTeam = Team();
final myCoach = Coach();
myTeam.coach = myCoach;
myCoach.team = myTeam;
print('All done!');
}
lazy initialization
オブジェクトを生成するとき、late
をつけているとイニシャライザでインスタンスメソッドにアクセスできる
-> という理解であってる?
-> 要するに使用するときに初めて初期化される?
class CachedValueProvider {
late final _cache = _computeValue();
int get value => _cache;
int _computeValue() {
print('In _computeValue...');
return 3;
}
}
void main() {
print('Calling constructor...');
var provider = CachedValueProvider();
print('Getting value...');
print('The value is ${provider.value}!');
}
このスクラップは2021/11/22にクローズされました