Dart 笔记 13 - 库

函数也是对象,类型是 Function。

bool isNoble(int atomicNumber) {
  return _nobleGases[atomicNumber] != null;
}

如果忽略了参数类型,函数仍然可以正常运行

isNoble(atomicNumber) {
  return _nobleGases[atomicNumber] != null;
}

只有一个表达式的函数,可以简写,类似 Kotlin。=> 后跟着一条表达式,不能是语句,比如 if 语句。

bool isNoble(int atomicNumber) => _nobleGases[atomicNumber] != null;

函数都有返回值,如果没有指定返回值,则隐式返回 null。

函数本身可以作为参数,返回值,赋值给变量。

可选参数

可选参数可以是位置参数,也可以是命名参数,但不能两者都是。

可选命名参数

定义参数时用 {} 括起来。如

void enableFlags({bool bold, bool hidden}) {...}

// 几种调用方法都可以
enableFlags(bold: true);
enableFlags(hidden: false);
enableFlags(bold: true, hidden: false);
enableFlags(hidden: false, bold: true);

如果要在可选命名参数中注释一个参数,使用 @required 说明它是一个必传的参数。

void enableFlags({bool bold, @required bool hidden}) {...}

enableFlags(bold: true); // 失败,必须有 hidden

Required 在元包中被定义。或者直接使用 import package:meta/meta.dart 导入或者导入其他包含 meta 导出的包,例如 Flutter 的包 Flutter /material.dart

可选位置参数

[] 包装参数。

String say([String device, int i]) {...}

// 如果有参数,第一个必须是 String 类型
say();
say('Bob');
say('Bob', 3);

默认参数值

void enableFlags({bool bold = false, bool hidden = false}) {...}

// bold will be true; hidden will be false.
enableFlags(bold: true);

String say([String device, int i=3]) {...}

say('Bob');

匿名函数

或叫 lambda 函数,或叫闭包函数,形如

([[Type] param1[, …]]) { 
  codeBlock; 
}; 

例如

var list = ['apples', 'bananas', 'oranges'];
// forEach 的参数就是一个匿名函数
list.forEach((item) {
  print('${list.indexOf(item)}: $item');
});

闭包

Function makeAdder(num addBy) {
  return (num 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);
}

makeAdder 返回一个函数,退出 makeAdder 函数后,返回的函数持有局部变量 addBy 的值,就是闭包。

typedef

class SortedCollection {
  Function compare;
  
  // 参数是一个函数
  SortedCollection(int f(Object a, Object b)) {
    // 当把函数赋值给 compare 时,f 的类型就丟了,compare 不知道它的参数列表,不知道它的返回值
    compare = f;
  }
}

int sort(Object a, Object b) => 0;

void main() {
  
  SortedCollection coll = SortedCollection(sort);

  // 只能知道 compare 是 Function,具体的函数签名就不知道了
  assert(coll.compare is Function);
}
// 使用 typedef 给函数起个别名,这样 Compare 类型就知道了
typedef Compare = int Function(Object a, Object b);

class SortedCollection {
  Compare compare;

  SortedCollection(this.compare);
}

int sort(Object a, Object b) => 0;

void main() {
  SortedCollection coll = SortedCollection(sort);
  assert(coll.compare is Function);
  assert(coll.compare is Compare);
}

因为 typedef 仅仅是别名,所以它们提供了一种检查任何函数类型的方法。

typedef Compare<T> = int Function(T a, T b);

int sort(int a, int b) => a - b;

void main() {
  assert(sort is Compare<int>); // True!
}

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券