Reputation: 395
The following:
import 'package:flutter/foundation.dart';
class Bar {
final int tender;
const Bar(this.tender);
}
class Foo {
final int foo;
final Bar bar;
const Foo({@required foo})
: foo = foo,
bar = const Bar(foo);
}
results in the compiler error "Arguments of a constant creation must be constant expressions" for the attempted initialization bar = const Bar(foo)
. Why does that line fail, when the preceding line foo = foo
does not?
EDIT Just to further clarify the source of confusion: effectively, it's as if it's ok to const-construct a Foo
with the argument foo
(which is unknown at compile-time), but it's not ok to const-construct a Bar
with the exact same argument. Why?
Upvotes: 2
Views: 185
Reputation: 1288
The line fails because a variable
is being passed instead of a constant/literal
to create the const
object of Bar
. The compiler doesn't know what foo
is going to be at compile time and hence it fails to create a const Bar(foo)
Consider this :
void main(){
int someNonConstantValue = 10;
const Bar(someNonConstantValue);
}
Compiler warns here with the same error message
Arguments of a constant creation must be constant expressions
This is because someNonConstantValue
is not a constant.
Now if the code is modified as :
void main(){
const int someConstantValue = 10;
const Bar(someConstantValue);
}
There are no warnings because compiler is now assured that someConstantValue
is actually constant and wont change anytime (and hence it can compile and optimize the code).
Similarly, In the original example, compiler doesn't give error if changes are made as such to use a constant literal
for creating const Bar(
class Bar {
final int tender;
const Bar(this.tender);
}
class Foo {
final int foo;
final Bar bar;
const Foo({@required this.foo})
: bar = const Bar(10);
}
Addition :
Following the same explanation as above, error is given if const Foo(
is passed a variable
void main(){
int someNonConstantValue = 10;
const Foo(foo:someNonConstantValue);
}
The point you are referring to is the constructor declaration
inside its own class. It hasn't been invoked with any value yet.
EDIT:
This github issue is a discussion on similar lines from early days of Dart.
This answer provides explanation about the same.
Upvotes: 3