概述
前面学习完Flutter的如何声明变量的基础知识之后,那么接下来就是该学习如何声明方法了。Function的用法非常灵活和多样,作为初学者的话,先掌握一些基础,以便后续学习Flutter可以更容易上手,等具备一些基础之后再去进阶会容易很多。个人见解,也是我目前的一个学习方式。
方法
- 如何声明一个方法
- 方法如何传参
- 返回值
1. 声明一个方法
Dart中声明一个方法和Java其实很相似的,但是限制条件却没有Java那么多。如:
csharp
bool isNode(int atomicNumber) {
return _nobleGases[atomicNumber] != null
}
省略返回值也是可以的:
javascript
isNode(int atomicNumber) {
return _nobleGases[atomicNumber] != null
}
但是,如果是作为公开的方法的话,不是很推荐这种不明确返回值的写法,这样对于使用的人来说不确定这个方法的返回值是什么类型。 针对这种只有一行表达式的方法,还可以简化一下写法:
scss
isNode(int atomicNumber) => _nobleGases[atomicNumber] != null
2. 方法传参
Dart中方法传参可以说是非常灵活了。可以像Java一样的普通穿惨,如:
csharp
bool isNode(int atomicNumber) {
return _nobleGases[atomicNumber] != null
}
还可以通过命名参数的方式,如:
arduino
/// Sets the [bold] and [hidden] flags ...
void enableFlags({bool? bold, bool? hidden}) {
...
}
命名参数的所有参数默认都是可选的,如果想要其中一个参数成为必须传,有两种方式。 第一种方式是移出{},如:
arduino
/// Sets the [bold] and [hidden] flags ...
void enableFlags(bool? bold,{bool? hidden}) { //参数bold为必传参数
...
}
第二种方式是通过require关键字,如:
dart
const Scrollbar({super.key, required Widget child});
两种方式没什么太大的区别,看习惯吧,移出{}的好处就是可以不用通过参数名的方式去给参数赋值,但是得按照参数顺序传值;通过require关键字的好处就是参数顺序可以不用固定,只要参数命名对的就行。所以看个人习惯吧。 针对可选参数,还有一种方式,就是用[]符号包裹。如:
arduino
/// Sets the [bold] and [hidden] flags ...
void enableFlags(bool? bold,[bool? hidden]) { //参数bold为必传参数
...
}
{}和[]的主要区别在于{}是命名参数的可选方式,而[]包括的可选参数是强调位置的,也就是说传递参数必须按位置顺序。这其实就透露出一个问题,如果可选参数超过2个,那如果第一个参数不传的话,第二个参数也是没办法穿的。所以说如果当你的可选参数只有一个的时候,用[]会方便一点,如果超过2个的话,除非这2个参数有依赖性,也就是传后面的参数如果要传,则前面的参数也是一定会传的情况下可以使用。否则用{}会更方便一些。 注:如果是可选参数,除非设置默认值,否则都需要声明为可空参数。
3. 方法参数
在Dart语言中,官方有一个说法叫:函数是一级对像,因此方法也是可以作为参数的,如:
scss
void printElement(int element) {
print(element);
}
var list = [1, 2, 3];
// Pass printElement as a parameter.
list.forEach(printElement);
而且还可以给方法声明为一个变量,如:
dart
var loudify = (msg) => '!!! ${msg.toUpperCase()} !!!';
assert(loudify('hello') == '!!! HELLO !!!');
给方法声明一个变量的方式常见于匿名函数,Lambdas或者是闭包, 如:
ini
const list = ['apples', 'bananas', 'oranges'];
upperCase(item) => item.toUpperCase();
var uppercaseList = list.map(upperCase).toList();
Function(dynamic) printString = (dynamic item) => print('$item: ${item.length}');
uppercaseList.forEach(printString);
词法闭包
直接上官方例子,其实关键词挺难理解的,我也不太理解词法闭包的标准含义是什么。但不得不说这个还挺有意思的,就像创建对象一样创建方法。这也印证了前面提到的方法是一级对象这个说法。
scss
/// Returns a function that adds [addBy] to the
/// function's argument.
Function makeAdder(int addBy) {
return (int i) => addBy + i;
}
void main() {
// Create a function that adds 2.
var add2 = makeAdder(2);
// Create a function that adds 4.
var add4 = makeAdder(4);
assert(add2(3) == 5);
assert(add4(3) == 7);
}
4. 返回值
按照官方的说法就是,所有的方法都有返回值.要么有具体的返回值,要么就是默认返回null。如:
scss
foo() {}//这个方法的没有写返回值,但是系统会有一个默认返回值,返回的是null
print(foo() == null);
之前在写Java的时候,一旦遇到需要返回多个值的时候,要么创建对象,要么通过Pair或者Triple这种关键字把它包裹起来。而在Dart中,相对就更方便一些,不需要任何关键字去包裹
javascript
(String, int) foo() { //(String, int)定义好了多个返回参数的类型
return ('something', 42);
}
关于Dart方法部分的一些基础知识基本上到此就差不多了。