Dart: General

 14th December 2020 at 10:22am

null 值的处理

b ??= val;

如果 b 的原始值是 null,它被赋值为 val;否则保留原值。

a = value ?? 0;

如果 value 为空,a 被赋值为 0;否则 avalue 赋值。

a?.b

等同于 a == null ? null : a.b

Typedefs

Dart 中 typedef 用来作为一个函数类型签名(包含参数类型和返回类型)的别名:

typedef Compare = int Function(Object a, Object b);

比如上面的 Compare,表示了一个接受两个 Object 作为参数、返回 int 类型的函数签名。

typedefs 的作用在于使函数类型签名,在编译期和运行期都能被 IDE 和 Dart 理解及使用。

比如这个例子,运行时你只能知道 coll.compare 是个函数,但是它是怎样的(什么参数类型、返回类型)函数,无法通过代码表达出来(即使 Dart runtime 是知道的):

class SortedCollection {
  Function compare;

  SortedCollection(int f(Object a, Object b)) {
    compare = f;
  }
}

// Initial, broken implementation.
int sort(Object a, Object b) => 0;

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

  // All we know is that compare is a function,
  // but what type of function?
  assert(coll.compare is Function);
}

使用 typedef 后则可以表达:

typedef Compare = int Function(Object a, Object b);

class SortedCollection {
  Compare compare;

  SortedCollection(this.compare);
}

// Initial, broken implementation.
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!
}

Metadata

比如 @deprecated@override

class Television {
  /// _Deprecated: Use [turnOn] instead._
  @deprecated
  void activate() {
    turnOn();
  }

  /// Turns the TV's power on.
  void turnOn() {...}
}

可以自定义自己的 metadata annotation。在运行时可以通过反射机制读取到。

Documentation comments

/// A domesticated South American camelid (Lama glama).
///
/// Andean cultures have used llamas as meat and pack
/// animals since pre-Hispanic times.
class Llama {
  String name;

  /// Feeds your llama [Food].
  ///
  /// The typical llama eats one bale of hay per week.
  void feed(Food food) {
    // ...
  }

  /// Exercises your llama with an [activity] for
  /// [timeLimit] minutes.
  void exercise(Activity activity, int timeLimit) {
    // ...
  }
}