Dart 点将台 | 函数的使用

一、函数的定义

1. Dart 中的函数定义

Dart 中,没有函数关键字,定义格式如下:

1double getBMI(double height, double weight){
2  return weight / (height * height);
3}

上面 getBMI 是一个最简单的函数形式,通过身高和体重计算 BMI 值。

1main() {
2  double height = 1.8;
3  double weight = 73;
4
5  double bmi = getBMI(height, weight);
6  print(bmi); // 22.530864197530864
7}

现在来对这个方法进行拓展,现在想要在计算时适应将不同的单位。不然,高度传入 厘米 ,体重传入 ,用上面的函数就无法得到正确的结果。

2.命名参数

LengthUnit 枚举是长度单位。方法定义中,通过 {} 包裹的参数可以设置 默认参数 ,在传参时 指定名称 进行传递,这里称其为 命名传参{} 中可以放多个参数,使用时 不需要 按顺序传递。注意:这样的参数只能放在参数列表的最后。

1enum LengthUnit { mm, cm, dm, m,km }
2
3double formatLength(double length, {LengthUnit lengthUnit = LengthUnit.m}) {
4  switch (lengthUnit) {
5    case LengthUnit.mm:
6      return length / 1000;
7    case LengthUnit.cm:
8      return length / 100;
9    case LengthUnit.dm:
10      return length / 10;
11    case LengthUnit.m:
12      return length;
13    case LengthUnit.km:
14      return length*1000;
15    default:
16      return height;
17  }
18}

上面一段代码中,通过 formatLength 函数,将传入 length 长度转换为标准单位 。比如 1.8 km 通过该方法可以转化为 1800.0 m 。  180 cm 可以转化为 1.8 m

1main() {
2  double height1 = formatLength(180);
3  double height2 = formatLength(180, lengthUnit: LengthUnit.cm);
4  double height3 = formatLength(1.8, lengthUnit: LengthUnit.km);
5
6  print(height1); // 180.0
7  print(height2); // 1.8
8  print(height3); // 1800.0
9}

3. 可选参数

WeightUnit 枚举是重量单位。方法定义中,通过 [] 包裹的参数可以设置 默认参数 ,在传参时可以选择传或不传, [] 中可以放多个参数,使用时 需要 按顺序传递。注意:这样的参数只能放在参数列表的最后。所以 {}[] 是冲突的,不能一起用。

1enum WeightUnit { g, jin, kg, t }
2
3double formatWeight(double weight, [WeightUnit weightUnit = WeightUnit.kg]) {
4  switch (weightUnit) {
5    case WeightUnit.g:
6      return weight / 1000;
7    case WeightUnit.jin:
8      return weight / 2;
9    case WeightUnit.kg:
10      return weight;
11    case WeightUnit.t:
12      return weight * 1000;
13    default:
14      return weight;
15  }
16}

4. 命名参数 和 可选参数

如下,使用 命名参数 ,调用方法传参时, {} 中的参数顺序不需要一致,指定名称即可。这样更加方便,语义性也很好。就是写起来比较麻烦一点。

1double bmi = getBMI(180146,
2    weightUnit: WeightUnit.jin,
3    lengthUnit: LengthUnit.cm);
4
5
6double getBMI(double height, double weight,{
7  LengthUnit lengthUnit = LengthUnit.m,
8  WeightUnit weightUnit = WeightUnit.kg
9}){
10  height = formatLength(height, lengthUnit: lengthUnit);
11  weight = formatWeight(weight, weightUnit);
12  return weight / (height * height);
13}

如下,使用 可选参数 ,调用方法传参时, [] 中的参数顺序需要一致。写起来比较简单,但语义上不明显。限制比较大,比如只想传 重量单位 时,必需为前面的 长度单位 也赋值,不够灵活。总的来说,如果参数过多 {} 比较好,用 [] 不太灵活,如果参数较少,使用 [] 比较简单。

1double bmi = getBMI(180146,
2    LengthUnit.cm, WeightUnit.jin);
3
4double getBMI(double height, double weight,[
5  LengthUnit lengthUnit = LengthUnit.m,
6  WeightUnit weightUnit = WeightUnit.kg
7]){
8  height = formatLength(height, lengthUnit: lengthUnit);
9  weight = formatWeight(weight, weightUnit);
10  print(height);
11  return weight / (height * height);
12}

二、函数的简化

dart 中对应函数非常灵活,可以简写很多东西,但有些简写会造成阅读的障碍,可读性较差,不建议使用。

1int add(int a, int b) {
2  return a + b;
3}

1.返回值省略

方法的返回值会自己推导,但为了 代码可读性 ,建议写上 返回值类型

1add(int a, int b) {
2  return a + b;
3}

2.类型省略

方法在入参时,会进行类型推导,但为了 代码可读性 ,建议写上 返回值类型

1add( a, b) {
2  return a + b;
3}

3.单行语句简写

当函数体只有一行时,可以使用 => 简写。这可以避免 {} 的包裹,可以使用。

1add(a, b) => a + b;

三、Dart 中的函数类型

1.函数的运行时类型

Dart 中一切皆对象,包括函数本身。也有通过 runtimeType 查看函数的运行时类型,如下。

1double getBMI(double height, double weight,
2    {LengthUnit lengthUnit = LengthUnit.m,
3    WeightUnit weightUnit = WeightUnit.kg}) {
4  height = formatLength(height, lengthUnit: lengthUnit);
5  weight = formatWeight(weight, weightUnit);
6  print(height);
7  return weight / (height * height);
8}

2.函数参数

通过 typedef 可以定义函数类型。如下,在 add 方法中加一个 operation 的函数,先对入参进行处理。这样可以实现 平方和、立方和等。在查看 operation 入参的 runtimeType 时,仍是 (int) => int 函数类型。

1main(){
2  add(3,4,operation:(value)=>value*value)
3}
4
5typedef Operation = int Function(int num);
6
7int add(int a, int b, Operation operation) {
8  return operation(a) + operation(b);
9}