Reputation: 2814
This snippet is of no practical significance. I've been just getting used to the closure idea.
var cls = () {
var x = 5;
return {
'x': x,
'inc': () {x++;},
};
} ();
void main() {
print(cls['x']);
print(cls['inc']);
cls['inc']();
print(cls['x']);
}
DartPad output:
5
Closure '_closure'
5
Error compiling to JavaScript:
main.dart:18:13:
Error: The method 'call' isn't defined for the class 'dart.core::Object'.
The desired output would have been something like
5
6
What'd be the cleanest approach to this kind of exercise?
UPD:
The working example, courtesy of Günter Zöchbauer:
var cls = () {
var x = 5;
var map = <String, dynamic>{
'x': x,
};
map['inc'] = () {map['x']++;};
return map;
} ();
void main() {
print(cls['x']);
print(cls['inc']);
cls['inc']();
print(cls['x']);
}
DartPad output:
5
Closure '_closure'
6
Upvotes: 3
Views: 2465
Reputation: 4015
You have to declare the 'x' entry as a Function.
In your code, you set 'x' to the value of the 'x' variable (5) when you return the map. The value will always be 5 and will not update.
var cls = () {
var x = 5;
return {
'x': () => x,
'inc': () {x++;},
};
}();
void main() {
print(cls['x']()); // 5
print(cls['x']); // Closure: () => int
print(cls['inc']); // Closure: () => Null
cls['inc']();
print(cls['x']()); // 6
}
Upvotes: 4
Reputation: 657781
var x = 5;
var cls = () {
return {
'x': x,
'inc': () {x++;},
};
} ();
You would need to move out the variable declaration, otherwise you'd re-declare and re-initialize it to 5
at every call.
update
var cls = () {
var x = 5;
var map = {
'x': x,
// 'inc': () {map['val']++;}, // not possible to reference the `map` variable that is just declared here so we need to move this out
};
map['inc'] = () {map['x']++;};
} ();
Upvotes: 2