Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

List as optional constructor parameter is null #41574

Closed
erf opened this issue Apr 19, 2020 · 12 comments
Closed

List as optional constructor parameter is null #41574

erf opened this issue Apr 19, 2020 · 12 comments
Labels
area-language Dart language related items (some items might be better tracked at github.com/dart-lang/language). closed-as-intended Closed as the reported issue is expected behavior type-question A question about expected behavior or functionality

Comments

@erf
Copy link

erf commented Apr 19, 2020

I would like to pass an optional named (growable) list as a constructor parameter.

I declare an empty list in the class.

When i do create a class, but dont pass a parameter for the list, it is set to null. I expected an empty list in the assertion.

Example:

class MyListClass {
  List myList = [];

  MyListClass({this.myList});
}

void main() {
  final obj = MyListClass();
  assert(obj.myList != null);
}

See my stack overflow question here:
https://stackoverflow.com/questions/61303649/initialise-class-parameter-with-default-value

Not sure if it is related to:
#21406

dart --version

Dart VM version: 2.7.2 (Mon Mar 23 22:11:27 2020 +0100) on "macos_x64"

im on macOS 10.15.4

@mraleph
Copy link
Member

mraleph commented Apr 19, 2020

This is working as intended. Default value for your named parameter is null, so you initialize the field with null if you don't pass anything.

@mraleph mraleph closed this as completed Apr 19, 2020
@mraleph mraleph added area-language Dart language related items (some items might be better tracked at github.com/dart-lang/language). closed-as-intended Closed as the reported issue is expected behavior type-question A question about expected behavior or functionality labels Apr 19, 2020
@erf
Copy link
Author

erf commented Apr 19, 2020

@mraleph i would expect the the value to be null only if i set MyListClass(myList: null)

What is the best way to optionally assign a list, but default to an empty ( growable ) list?

@mraleph
Copy link
Member

mraleph commented Apr 19, 2020

When you write f({this.x}) that means f({this.x : null}).

Default initializers can only be constants, so your best bet is f({List x}) : x = x ?? [];

@perfoWorks
Copy link

perfoWorks commented Apr 19, 2020

@mraleph Is there any change in dart language? Because this was working few releases ago... I have removed constructor and it works as intended class MyListClass { List myList = [];} Another thing .. what is the point of the constructor now? Do we need to create a constructor? I have removed all my constructors in my classes which were needed in previous versions and now I've got no issue without them

@mraleph
Copy link
Member

mraleph commented Apr 19, 2020

Is there any change in dart language?

No, this was always supposed to work like that.

Because this was working few releases ago...

I am fairly certain it did not actually work and you are misremembering.

I have removed constructor and it works as intended class MyListClass { List myList = [];}

Except that now you can't do MyListClass(myList: something).

Another thing .. what is the point of the constructor now? Do we need to create a constructor?

The point of constructor is to contain initialization code which can't be expressed just in terms of field initializers and to call appropriate super constructor.

If you don't create a constructor you get default constructor - which is empty and is calling default super constructor.

I have removed all my constructors in my classes which were needed in previous versions and now I've got no issue without them

Well if you never called your constructors with parameters and you only need field initializers - then you certainly don't need any constructors.

@perfoWorks
Copy link

Except that now you can't do MyListClass(myList: something).

Right... sorry that is correct

@mrvincenzo
Copy link

When you write f({this.x}) that means f({this.x : null}).

Default initializers can only be constants, so your best bet is f({List x}) : x = x ?? [];

This f({List x}) : x = x ?? []; won't work since [] is Invalid const value so AFAICS the best bet is to f({List x}) { this.x = x ?? []; }.

@mraleph
Copy link
Member

mraleph commented Jan 25, 2021

This f({List x}) : x = x ?? []; won't work since [] is Invalid const value so AFAICS the best bet is to f({List x}) { this.x = x ?? []; }.

There is nothing in f({List x}) : x = x ?? []; that requires [] to be a constant value, so it works perfectly fine. Try it in an editor or dartpad.

@eernstg
Copy link
Member

eernstg commented Jan 25, 2021

This f({List x}) : x = x ?? []; won't work since [] is Invalid const value

As @mraleph mentioned, it is not an error to use a non-constant expression in an initializer list. But it may be helpful to go back to the complete example where it's explicitly about a constructor:

class MyListClass {
  final List myList; // Also not a problem with `final`.
  MyListClass({List? x}) : myList = x != null ? x : [];
}

(If you're using a version of Dart that doesn't support null safety then you need to delete the ? from List?.)

@mraleph
Copy link
Member

mraleph commented Jan 25, 2021

@mraleph You are right. In my setup I had the x property defined as final.

final should not matter. However you can get an error like this if you also declare your constructor as const. (In which case this.x = x ?? [] would not work either anyway).

@mrvincenzo
Copy link

@mraleph You are right again. I rechecked everything and f({List x}) : x = x ?? []; both for final and not final property work just fine. Not sure why it didn't work for me for the first time.

@jubayer040
Copy link

this method work for mee.
class DoctorInfo{
final List info;
final int value;
final int id;

  const DoctorInfo({  
                 this.info = const [] ,   // only addind const keyword fixed my prb
                 required this.value,
                 this.id=0 
  });

}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-language Dart language related items (some items might be better tracked at github.com/dart-lang/language). closed-as-intended Closed as the reported issue is expected behavior type-question A question about expected behavior or functionality
Projects
None yet
Development

No branches or pull requests

6 participants