There are two ways of defining a function or method parameter type, when such type is a flavor of Function
that needs to be defined
inline:
- using the generic function syntax:
void Function(int) parameterName
- using the legacy function syntax:
void parameterName(int)
The first option should be preferred in all circumstances, for the following reasons:
Readability
Unlike non-Function
type, which always preceed the parameter name (e.g. int x
, List<int> y
,
Map<String, double>? z
, etc.), Function
types expressed using the legacy syntax are intermingled with the parameter
name. Specifically, part of the type, namely the return type of the Function
, is placed before the parameter name, whereas the list of
formal parameters of the Function
is placed after.
void aFunction(void parameterName(int functionParameterName)) {
// ...
}
That makes the code harder to read and understand. For instance, it’s not easy to tell at a first glance that functionParameterName
is
not a parameter of aFunction
, but a parameter of the Function
parameter parameterName
of
aFunction
.
Consistency
Pretty much like the function syntax, also the typedef
syntax has two forms:
- the generic
typedef
syntax: typedef void MyFunction(int);
- the legacy
typedef
syntax: typedef MyFunction = void Function(int);
The first option is more powerful and flexible, as explained in S5416.
The generic typedef
syntax matches syntactically the generic function syntax defined inline. Using syntaxes consistently allows easier
code maintenance and refactoring.
For example if an inline generic function syntax needs to be extracted into a generic typedef
syntax, for its complexity, number of
occurrences, or to be exposed outside the current library, the refactoring is easier and less error-prone, since the right-end side of the
typedef
is the same as the inline type definition.
// Before extraction of typedef using generic syntax
void aFunction(void Function(int functionParameterName) parameterName) {
// ...
}
// After extraction of typedef using generic syntax
typedef MyFunction = void Function(int functionParameterName);
void aFunction(MyFunction parameterName) {
// ...
}
The same is not true for the legacy syntax:
// Before extraction of typedef using legacy syntax
void aFunction(void parameterName(int functionParameterName)) {
// ...
}
// After extraction of typedef using legacy syntax
typedef void MyFunction(int functionParameterName);
void aFunction(MyFunction parameterName) {
// ...
}