7

The following code does not compile with sound null safety because it is possible to pass null to the constructor which initializes a non-nullable field myString.

class MyClass {
  String myString;
  MyClass({@required this.myString});
}

I would expect that adding a question mark after this.myString would solve the problem, but it doesnt and another compile error is shown.

A default value is no option for me and it seems that the only other solution is something like this:

class MyClass {
  late String myString;
  MyClass({@required myString}) {
    this.myString = myString;
  }
}

Imo this decreases readability if there are a lot of parameters. Is there a more convenient solution which suppports initialization with this. in named constructors?

Bobin
  • 278
  • 5
  • 15
  • 4
    Use the new keyword "required" instead of "@required". It is documented here: https://dart.dev/null-safety/understanding-null-safety#required-named-parameters – julemand101 May 24 '21 at 12:10
  • There is no other way. If you check the internal code of any of Flutter's widgets, you would find the same pattern. But yeah `required` instead of `@required` – Nisanth Reddy May 24 '21 at 12:42
  • @NisanthReddy What do you mean by "there is no other way"? His first example would work fine if he just replace `@required` with `required`. – julemand101 May 24 '21 at 17:20
  • @julemand101 I meant other than using the one he mentioned, there would be no other way – Nisanth Reddy May 24 '21 at 17:29

2 Answers2

9

For non-nullable types, either use required or provide a default value. You can also use late but make sure to provide a value at some later point before using it. It's like a bang operator.

Example:

class Foo {
  // All are non-nullable.
  final int a;
  final int b;
  late final int c; // I trust you that you'll provide me a value later. 
  
  Foo({
    required this.a, // <-- Mark it required  
    this.b = 0, // <-- or provide a default value. 
  });
}
CopsOnRoad
  • 237,138
  • 77
  • 654
  • 440
2

If i am not getting the idea wrong, if you want to have a String param which is nullable from the constructor, you can declare a 'String?' type.

class MyClass {
  String? myString;
  MyClass({required this.myString});
}
CbL
  • 734
  • 5
  • 22