“This is the 20th day of my participation in the Gwen Challenge in November. Check out the details: The Last Gwen Challenge in 2021.”
preface
In Dart, functions are also objects, so they can be passed or used as normal variables at any time. The difference is that functions can take parameters, and Dart also has lambda functions. When using functions, we also need to follow certain specifications to make our code easier to read.
Specification 1: For named functions, use declarations
In modern programming languages, it is easy to create anonymous functions, such as the use of closures. Other functions can also be defined inside functions to implement nested calls. In most cases this approach is suitable for immediate callbacks. However, if a function needs to be named, it should be declared, not assigned. For example:
// Correct example
void main() {
voidlocalFunction() { ... }}Error Example 1
void main() {
var localFunction = () {
...
};
}
// Error Example 2
void main() {
var localFunction = () => something;
}
Copy the code
Specification 2: Pass functions as arguments instead of creating lambda functions
In some cases, we need to call another function within a function to process an object. The usual way to do this is to create a lambda. But if the called function is already defined, don’t create a lambda function because Dart provides a way to pass the function as an argument. If it sounds a little loopy, let’s look at an example where we want to loop through an array of names. Dart allows you to pass the print method to forEach each element directly.
var names = ['Bobby'.'Jack'.'Rose'];
// Correct example
name.forEach(print);
// Error example
name.forEach((name) {
print(name);
});
Copy the code
Specification 3: Use the = operator to set default values for named parameters
Dart functions support named parameters, which are defined as follows:
void someFunction(Object item, {required int a, int b = 0.Object? c}) {
...
}
Copy the code
The first parameter item is a non-named parameter, the second parameter a is a mandatory named parameter, the third parameter B is a non-mandatory parameter (with a default value), and the fourth parameter is a nullable parameter (optional or null). Dart supports using colons to set defaults, but not recommended:
// Error example
void someFunction(Object item, {required int a, int b: 0.Object? c}) {
...
}
Copy the code
Specification 4: Type declarations precede parameters instead of using colons to declare types
In fact, this is a mistake, but also an accidental discovery. Some languages, such as Swift and Kotlin, place type declarations after parameters.
/ / swift function
func sayHello(name: String) -> Void {
print( "Hello, \(name)");
}
Copy the code
/ / Kotlin function
fun sayHello(name: String) {
println("Hello, $name");
}
Copy the code
Initially, if you switch from these two languages to Dart, you might write similarly, and Dart doesn’t report errors!
void sayHello({name: String{})print('Hello, $name');
}
Copy the code
That works, too. How does that work? In fact, in Dart, all types are also objects, so in the code above, name is actually of type Dynamic, except that the initial value is a String object. Let’s print it out.
void sayHello({name: String}) {
print(name);
print(name.runtimeType);
print('Hello, $name');
}
sayHello();
sayHello(name: 'Jack');
/ / the result
String
Type
Hello, String
Jack
String
Hello, Jack
Copy the code
As you can see, the type changes dynamically with the parameters passed in, so this is a bad use!
Specification 5: Use function aliases wisely
Many times we can pass functions as arguments for callbacks. Using a generic Function type like Function can work, but it makes the code less readable, and declarations like Function can accept any form of callback methods, such as the following is not recommended.
// Error example
void callbackFunc({callback: Function}) {
callback();
}
callbackFunc(callback: () {
print('Hello! ');
});
Copy the code
The correct way to do this is to set a function alias, such as VoidCallBack (ValueChanged) that comes with Flutter.
// Correct example
typedef VoidCallback = void Function(a);typedef ValueChanged = void Function<T>(T value);
void callbackFunc({callback: ValueChanged}) {
callback('Jack');
}
callbackFunc(callback: (name) {
print('Hello, $name');
});
Copy the code
This way you know exactly what parameters and return values are required for the callback function, and your code is much more robust.
conclusion
Dart is a flexible programming language, but it can be written differently, which can lead to uneven code quality. Therefore, the development of the best reference to the official formulation of internal norms, in order to ensure the rationality of coding.
I am dao Code Farmer with the same name as my wechat official account. This is a column about the introduction and practice of Flutter, providing systematic learning articles about Flutter. See the corresponding source code here: The source code of Flutter Introduction and Practical column. If you have any questions, please add me to the wechat account: island-coder.
👍🏻 : feel the harvest please point a praise to encourage!
🌟 : Collect articles, easy to look back!
💬 : Comment exchange, mutual progress!