I made a class HelloWorld
with a named constructer which accepts a single parameter named test
which also has default value of Default Value
. Here is my code:
import 'dart:core';
class HelloWorld {
final String test;
const HelloWorld({
this.test = 'Default Value',
});
}
void main() {
const Map<String, dynamic> _json = {'hello': 'world'};
const _helloWorld = HelloWorld(test: _json['test']);
print(_helloWorld.test);
}
Then I made a map named _json
which has only one key hello
. Finally I tried to get the value of key test
which obviously doesn't exist in _json
which will return null
. Despite having the default value for the test
parameter in the named constructor, I still get this compilation error:
lib/main.dart:13:23:
Error: Constant evaluation error:
const _helloWorld = HelloWorld(test: _json['test']);
^
lib/main.dart:13:45:
Info: The method '[]' can't be invoked on '<String, dynamic>{"hello": "world"}' in a constant expression.
const _helloWorld = HelloWorld(test: _json['test']);
^
lib/main.dart:13:9:
Info: While analyzing:
const _helloWorld = HelloWorld(test: _json['test']);
^
Error: Compilation failed.
Dart version: Dart SDK version: 2.14.4 (stable) (Wed Oct 13 11:11:32 2021 0200) on "macos_x64"
CodePudding user response:
const means that the object's entire deep state can be determined entirely at compile time and that the object will be frozen and completely immutable.
const Map<String, dynamic> _json = {'hello': 'world'};
means this _json
is compile-time constant.
But for _json['test']
it doesn't know what will be the value of it in compile time. It needs to go through the _json
Map and find the value, and this will happen while running the code. For this reason _helloWorld
can not be a const.
But if you do HelloWorld(test: "others");
or use default value HelloWorld()
, the _helloWorld
can be const
type.
void main() {
const Map<String, dynamic> _json = {'hello': 'world'};
final _helloWorld = HelloWorld(test: _json['test']); // or can be use String
print(_helloWorld.test);
const _helloWorld1 = HelloWorld();
print(_helloWorld1.test);
const _helloWorld2 = HelloWorld(test: "on _helloWorld2");
print(_helloWorld2.test);
}
Default value will be available only when you don't pass any value using test
, it will be const _helloWorld1 = HelloWorld();
.
But for handling null-Value from _json
you can use HelloWorld(test: _json['test'] ?? "Got Null");
. Passing Got Null
because test
require a non-nullable String
. If you wish to have constructor default value in this case, check _json['x']
provide null or not, then assign on _helloWorld
.
final _helloWorld = _json['test'] == null
? HelloWorld()
: HelloWorld(test: _json['test']);
I will recommend const and final SO answerto learn more it. Also, you can find on dart.dev
CodePudding user response:
I ended up using this way:
import 'dart:core';
class HelloWorld {
final String test;
const HelloWorld({
String? test,
}) : test = test ?? 'Default Value';
}
void main() {
final Map<String, dynamic> _json = {'hello': 'world'};
final _helloWorld = HelloWorld(test: _json['test']);
print(_helloWorld.test);
}
CodePudding user response:
You simply need to change your test variable to this, to make it nullable:
final String? test;