I created a literal map of closures, something like:
Map<String, Function> mapOfFuncs = {
'foo': (a, b, c) => ... ,
'bar': (a, b, c) => ... ,
...
}
All good so far. Then I wanted to make this map const
, as it is global within my program and should never be modified.
const Map<String, Function> MAP_OF_FUNCS = const {
'foo': (a, b, c) => ... ,
'bar': (a, b, c) => ... ,
...
}
Dart chokes on this as the literal closures in the map are not const
.
On Dartpad: https://dartpad.dartlang.org/817d2cfd141b0a56fc7d
I would have thought that literal closures are const
. Is there a way to make them so?
I suspect this might not be possible, take a look at this code:
int test1(int a, int b, int c) {
return a;
}
int test2(final int a, final int b, final int c) {
return a;
}
const Function f1 = test1;
const Function f2 = (final a,b,c) => a;
const Map<String, Function> MAP_OF_FUNCS = const {
'foo': test1,
'fam': test2,
'bam': f1,
'bar': f2
};
Only the first two versions referencing the static method references test1
and test2
work in this constellation. Even f1
produces a compilation error, UPDATE but compiles using dartJS as @irn from the comments pointed out. Then it is unclear why the version with f2
doesn't work.
So probably it is the assignment operator which is not able to produce a statically compiled reference for a given constant lambda expression or a static method reference for its RHS (right hand side) argument.
The documentation pointed me in testing the static const
combination, but this generally only works on non top level elements like class members. Thus adding a new class makes it possible to test this.
class A {
static const Function a1 = test1;
static const Function a2 = (final a, final b, final c) => a;
}
const Map<String, Function> MAP_OF_FUNCS = const {
'foo': A.a1,
'bar': A.a2
};
However, these function definitions are valid but assigning it to the map fails as before. The documentation about maps under the built in types section shows how to create a compile time constant map using the final
keyword.
final constantMap = const {
2: 'helium',
10: 'neon',
18: 'argon',
};
Unfortunately, this approach has the same drawback. It might corellate with the minification limitations of symbols:
A Symbol object represents an operator or identifier declared in a Dart program. You might never need to use symbols, but they’re invaluable for APIs that refer to identifiers by name, because minification changes identifier names but not identifier symbols. ... Symbol literals are compile-time constants.
For more information on symbols, see dart:mirrors - reflection.
Maybe someone else has a better idea, but for me this seems not possible for the moment.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With