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を投げる
  • latefinalと一緒に使うこともできる
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にクローズされました