preface
Functions are what we use most. They can break down complex business into short, concise functions, thereby breaking up large business and improving maintainability and code reuse. When designing a function, it is crucial to receive the parameters that define the input to the function. This article describes the proper use of the Dart function.
Dart function parameters
There are two ways to pass parameters to a function in Dart, including placeholder and naming, plus nullable and nullable, as shown below.
// The second parameter needs to be passed
void someFunction1(int a, String? b) {
// ...
}
// the second parameter is not passed
void someFunction2(int a, [String? b]) {
// ...
}
// In the form of a named parameter, p is a mandatory parameter
void someFunction4(int a, {required Person p, Student? s} ) {
// ...
}
// In the form of named arguments, p and c are optional
void someFunction4(int a, {Person? p, Student? s} ) {
// ...
}
Copy the code
Where the optional placeholder parameter uses […] Form, indicating that the parameters can be passed or not. Named parameters use {… }, if the parameter is required, it needs to be declared as required. Note that optional placeholder parameters and named parameters cannot be used at the same time, such as the following form will report an error.
/ / error! Optional placeholder parameters and named parameters cannot be shared
void someFunction4(int a, [String? b], {Person? p, Student? s} ) {
// ...
}
Copy the code
Since Dart comes in both forms, you can use either form, but you still need to follow certain specifications in practice.
Specification 1: Avoid placeholder passing for Boolean parameters
Since Boolean values are hard to literally know what they mean, Boolean arguments are less readable if passed as placeholders. In the following example, it is difficult to know what a Boolean value means without looking at the function definition, documentation, or internal code.
// Error example
// Create a single task
Task(true);
// Loop tasks
Task(false);
// What is this?
ListBox(false.true.true);
// Disable the state of button
Button(false);
Copy the code
In this case, constructors can be used in the form of named constructors or named parameters, which is semantically much clearer. The following code is understandable even without comments.
// Correct example
Task.oneShot();
Task.repeating();
ListBox(scroll: true, showScrollbars: true);
Button(ButtonState.enabled);
Copy the code
Of course, for setters, it’s okay to use booleans because of the context.
// Correct example
listBox.canScroll = true;
button.isEnabled = false;
Copy the code
Specification 2: For optional placeholder parameters, set reasonable order by frequency
Optional placeholder parameters mean that you don’t pass them, and if a less-used parameter comes first, you’ll have to assign a value to that parameter if you need to pass it, and null if you don’t have a value, which would be ugly code.
// Error example
void someFunction(int a, [int? b, int? c, int d = 0]) {
/ /...
}
// Call an example
someFunction(1.null.null.12);
Copy the code
In the above example, d might have been passed as an argument that was passed most often and ended up being passed last, causing the caller to be frustrated by having to pass NULL to B and C every time d was passed. The correct example is as follows:
// Correct example
void someFunction(int a, [int d = 0.int? b, int? c]) {
/ /...
}
// Call an example
someFunction(1.12);
Copy the code
In this case, of course, it makes more sense to use named parameters.
// Correct example
void someFunction(int a, {int d = 0.int? b, int? c}) {
/ /...
}
// Call an example
someFunction(1, d: 12);
Copy the code
Specification 3: Avoid requiring meaningless parameters to be passed
If we need to omit parameter passing, we should omit it directly, rather than passing meaningless arguments such as NULL, empty strings, etc. Omitting arguments looks cleaner and avoids null errors, which can make the function think it passed a meaningful argument.
// Correct example
var rest = string.substring(start);
// Error example
var rest = string.substring(start, null);
Copy the code
Specification 4: For range parameters, follow the convention that the start parameter is a closed interval and the end parameter should be an open interval
When we get a range value, we need to pass in a starting and ending position, usually an integer subscript, with a starting subscript indicating the number of elements to start with and an ending subscript indicating where to end. Since these types of parameters are usually placeholder parameters rather than named parameters, it is recommended that they be used in the same way as the Dart core library — the start position is included, the end position is not, and the mathematical interval is of the form [s, e]. Here is an example of the Dart core library:
// Correct example
[0.1.2.3].sublist(1.3) / / [1, 2]
'abcd'.substring(1.3) // 'bc
Copy the code
Specification 5: For optional parameters, try to set defaults
Optional parameters that have no default value will default to null if they are not passed. This can lead to bugs if used carelessly. Therefore, assuming you know the default state when coding, try to set the default value, as in the following DateTime and Duration examples:
// Correct example
DateTime(int year,
[int month = 1.int day = 1.int hour = 0.int minute = 0.int second = 0.int millisecond = 0.int microsecond = 0]);
Duration({int days = 0.int hours = 0.int minutes = 0.int seconds = 0.int milliseconds = 0.int microseconds = 0});
Copy the code
conclusion
This article introduces the Dart function parameter transfer form and five specifications. Personally, I prefer to use named parameters because the semantics of the parameters are made clear when a function is called — especially if there are many parameters. In addition, it is recommended to specify whether the parameter is required to constrain the parameter passing behavior of the caller. For optional parameters that know the default value, it is recommended to set the default value. This way we can omit a lot of null judgments.
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!