【问题标题】:How do I use Dart extension functions?如何使用 Dart 扩展功能?
【发布时间】:2020-02-05 20:26:46
【问题描述】:

Dart 2.6 引入了一个名为“static extension members”的新语言功能。
但是,我不太明白如何使用它。

我想轻松获得RowColumnchildCount,即使用row.childCount 而不是row.children.length

void main() {
  final row = Row(children: const [Text('one'), Text('two')]), 
      column = Column(children: const [Text('one'), Text('two'), Text('three')]);

  print(row.childCount); // Should print "2".

  print(column.childCount); // Should print "3".
}

我尝试执行以下操作,但这是语法错误:

Row.childCount() => this.children.length;

Column.childCount() => this.children.length;

【问题讨论】:

    标签: flutter dart


    【解决方案1】:

    现在有一个关于扩展方法的official video by the Flutter team

    静态扩展成员

    这是扩展方法如何工作的直观示例:

    extension FancyNum on num {
      num plus(num other) => this + other;
    
      num times(num other) => this * other;
    }
    

    我只是在这里扩展num 并向类添加方法。可以这样使用:

    print(5.plus(3)); // Equal to "5 + 3".
    print(5.times(8)); // Equal to "5 * 8".
    print(2.plus(1).times(3)); // Equal to "(2 + 1) * 3".
    

    请注意,名称 FancyNum 是可选的,以下也是有效的:

    extension on num {}
    

    当您在另一个文件中使用您的扩展程序时,您必须为其命名。


    上面的扩展将使用implicit extension member invocations,因为您不必将num 显式声明为FancyNum

    您也可以显式声明您的扩展,但在大多数情况下不需要这样做:

    print(FancyNum(1).plus(2));
    

    弹性子数

    问题的期望行为可以通过扩展RowColumn来实现,甚至更好:你可以扩展Flex,这是Row的超类 Column:

    extension ExtendedFlex on Flex {
      int get childCount => this.children.length;
    }
    

    如果children没有在childCount的当前词法范围内定义,this.也可以省略,这意味着=> children.length也是有效的。


    通过导入Flex 的这个静态扩展,您可以在任何Flex 上调用它,即也可以在每个RowColumn 上调用它。
    Row(children: const [Text('one'), Text('two')]).childCount 将评估到2

    【讨论】:

    • 这一行“当你在另一个文件中使用你的扩展名时,你必须给它一个名字。”谢谢
    【解决方案2】:

    Dart 2.7 引入了新的扩展方法概念。

    https://dart.dev/guides/language/extension-methods

    extension ParseNumbers on String {
        int parseInt() {
            return int.parse(this);
        }
        double parseDouble() {
            return double.parse(this);
        }
    }
    main() {
        int i = '42'.parseInt();
        print(i);
    }
    

    【讨论】:

      【解决方案3】:

      扩展可以有泛型类型参数。对于以下示例显示多个适用扩展可用时的隐式扩展分辨率。

      extension SmartIterable<T> on Iterable<T> {
        void doTheSmartThing(void Function(T) smart) {
          for (var e in this) smart(e);
        }
      }
      extension SmartList<T> on List<T> {
        void doTheSmartThing(void Function(T) smart) {
          for (int i = 0; i < length; i++) smart(this[i]);
        }
      }
      ...
        List<int> x = ....;
        x.doTheSmartThing(print);
      

      这两个扩展都适用,但 SmartList 扩展比 SmartIterable 扩展更具体,因为 List <:>Iterable<dynamic>。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-02-12
        • 1970-01-01
        • 2020-02-22
        • 2013-08-29
        • 1970-01-01
        • 1970-01-01
        • 2015-08-13
        • 2013-07-25
        相关资源
        最近更新 更多