When a widget has some logic (ex: if
/else
), if often see the logic being done at the beginning of the build method and stored in variables that are reused.
For example
Widget build(BuildContext context) {
// ... Some logic 0 here
final result0 = // ...
// ... Some logic 1 here
final result1 = // ...
// ...
return Column(
children: [
// ...
MyWidget0(
parameter: result0,
),
// ...
MyWidget1(
parameter: result1,
),
// ...
],
);
}
which I sometimes feel a bit hard to read as the logic of the widget x
is at the beginning and not with the widget x
itself.
I never see people using lambda methods like:
Widget build(BuildContext context) {
return Column(
children: [
// ...
MyWidget0(
parameter: () {
// ... Some logic 0 here
final result0 = // ...
return result0;
}(),
),
// ...
MyWidget1(
parameter: () {
// ... Some logic 1 here
final result1 = // ...
return result1;
}(),
),
// ...
],
);
}
This allows to have the logic x
next to the widget x
(where it is used).
And also, if MyWidget1
is not always built:
Column(
children: [
// ...
if (condition)
MyWidget1(
// ...
),
// ...
],
),
logic 1 won't be executed if condition
is false
; unlike in the first example where logic 1 is always run at the beginning of the build
method.
I was wondering if there were any drawbacks to using lambda functions in the build method as illustrated. Or if it is a bad practice, why?
There shouldn't be any difference. I'd expect the compiler to optimize the anonymous function usage so that both versions are equivalent. And indeed, using godbolt.org to examine the disassembled output, I don't see any difference between:
void main() {
print('foo');
}
and
void main() {
() { print('foo'); }();
}
Whether superfluous anonymous functions make build
methods more readable is subjective. I personally think that they would usually make code (especially the surrounding code) less readable due to the extra indentation and the increased space between arguments.