在 Dart 中,函数也是对象,就像字符和数字对象一样。 使用 typedef ,或者 function-type alias为函数起一个别名, 别名可以用来声明字段及返回值类型。 当函数类型分配给变量时,typedef会保留类型信息

    请考虑以下代码,代码中未使用 typedef:

    1. class SortedCollection {
    2. Function compare;
    3. SortedCollection(int f(Object a, Object b)) {
    4. compare = f;
    5. }
    6. }
    7. // Initial, broken implementation. // broken ?
    8. int sort(Object a, Object b) => 0;
    9. void main() {
    10. SortedCollection coll = SortedCollection(sort);
    11. // 虽然知道 compare 是函数,
    12. // 但是函数是什么类型 ?
    13. assert(coll.compare is Function);
    14. }

    当把 f 赋值给 compare 的时候,类型信息丢失了。 f 的类型是 (Object, Object) → int (这里 → 代表返回值类型), 但是 compare 得到的类型是 Function 。如果我们使用显式的名字并保留类型信息, 这样开发者和工具都可以使用这些信息:

    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);
    }
    

    ⚠️注意: 目前,typedefs 只能使用在函数类型上, 我们希望将来这种情况有所改变

    由于 typedefs 只是别名, 他们还提供了一种方式来判断任意函数的类型。例如:

    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!
    }
    
    typedef VoidCallback = void Function();
    
     const FlatButton({
        Key? key,
        required VoidCallback? onPressed,
        VoidCallback? onLongPress,
        ValueChanged<bool>? onHighlightChanged,
        MouseCursor? mouseCursor,
        ButtonTextTheme? textTheme,
        Color? textColor,
        Color? disabledTextColor,
        Color? color,
        Color? disabledColor,
        Color? focusColor,
        Color? hoverColor,
        Color? highlightColor,
        Color? splashColor,
        Brightness? colorBrightness,
        EdgeInsetsGeometry? padding,
        VisualDensity? visualDensity,
        ShapeBorder? shape,
        Clip clipBehavior = Clip.none,
        FocusNode? focusNode,
        bool autofocus = false,
        MaterialTapTargetSize? materialTapTargetSize,
        required Widget child,
        double? height,
        double? minWidth,
      }) : assert(clipBehavior != null),
           assert(autofocus != null),
           super(
             key: key,
             height: height,
             minWidth: minWidth,
             onPressed: onPressed,
             onLongPress: onLongPress,
             onHighlightChanged: onHighlightChanged,
             mouseCursor: mouseCursor,
             textTheme: textTheme,
             textColor: textColor,
             disabledTextColor: disabledTextColor,
             color: color,
             disabledColor: disabledColor,
             focusColor: focusColor,
             hoverColor: hoverColor,
             highlightColor: highlightColor,
             splashColor: splashColor,
             colorBrightness: colorBrightness,
             padding: padding,
             visualDensity: visualDensity,
             shape: shape,
             clipBehavior: clipBehavior,
             focusNode: focusNode,
             autofocus: autofocus,
             materialTapTargetSize: materialTapTargetSize,
             child: child,
          );