dart扩展函数的几种用法

简介:
从2.7及以上的dart版本开始,让人殷切期待的扩展函数来了。当你想扩展别人的函数库或者官方的SDK,如果通过更改api的方式则意味着你需要重建一个代码分支,维护一个分支是相当麻烦的事情, 如果这个时候使用扩展方法将是非常方便的。扩展不仅可以定义方法,还可以定义getter,setter和operator。虽然扩展方法中不能用于用dynamic类型,但却支持更强大的泛型扩展。总有人吐槽flutter开发widget嵌套太深的问题,扩展函数的使用能够让代码的结构变得极为简洁,加上泛型扩展的使用可以使代码链式调用一链到底。

原理:
扩展函数调用起来跟原生方法一样自然,使用起来也非常方便,但是这样的用法会不会带来性能方面的问题呢?其实扩展函数的本质是针对接收者的静态类型进行了解析,即扩展方法是静态解析的,扩展函数的实现非常简单,它没有修改接受者类型的成员,仅仅是通过静态方法来实现的,它们与调用静态函数一样快速。
废话少说,下面以本人开发中的使用的经验举几个例子加以说明。


widget扩展:
extension WidgetExt on Widget {
  Widget padding(EdgeInsetsGeometry padding) {
    return Padding(
      child: this,
      padding: padding,
    );
  }

  Material gesture({
    GestureTapCallback onTap,
    GestureTapCallback onDoubleTap,
    GestureLongPressCallback onLongPress,
  }) {
    return Material(
      child: InkWell(
        child: this,
        onTap: onTap,
        onDoubleTap: onDoubleTap,
        onLongPress: onLongPress,
      ),
    );
  }
}

String扩展:
extension StringExt on String {
  double toDouble() {
    return double.parse(this);
  }
  int toInt() {
    return int.parse(this);
  }
  bool isMobile(){
    return RegExp(r'^((13[0-9])|(14[5,7,9])|(15[^4])|(18[0-9])|(17[0,1,3,5,6,7,8])|(19)[0-9])\d{8}$').hasMatch(this);
  }
}

Object扩展:
extension ObjectExt on Object {
  bool isNullOrEmpty() {
    if (this is String)
      return (this as String).isEmpty;
    else if (this is Iterable) return (this as Iterable).isEmpty;
    return this == null;
  }
}

bool扩展:
extension BoolExt on bool {
  bool not() {
    return !this;
  }

  bool and(bool val) {
    return this && val;
  }

  bool or(bool val) {
    return this || val;
  }
}

泛型扩展:
extension AllExt<T> on T {
  T apply(f(T e)) {
    f(this);
    return this;
  }

  R let<R>(R f(T e)) {
    return f(this);
  }
}

调用示例如下:仅简单举几个调用例子,其余的调用有兴趣者自行尝试。

实现单层没有嵌的padding和点击事件

      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'You have pushed the button this many times:',
            )
                    .padding(EdgeInsets.all(10))
                    .gesture(onTap: () {
              
            }),
          ],
        ),
      ),

实现String正则的判断

      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              '13646176072'.isMobile()?"手机号":"不是手机号",
            ),
          ],
        ),
      ),

bool类型的链式调用

      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              ['13646176072', "fgdgdfgdf", 'trtreter']
                  .isNullOrEmpty()
                  .not()
                  .and(true)
                  .or(false)
                  .toString(),
            ),
          ],
        ),
      ),

泛型扩展的链式调用:这个用法非常值得一提,在原生开发中kotlin的语法糖是相当牛掰的,kotlin能够使代码的编写链成一整个链而不使用一个中间变量,这样使得代码优雅,封装的更完美。幸运的是dart虽然没有提供很多的语法糖,但却提供了泛型扩展函数,我们可以依此自定义非常强大的语法糖,调用示例如下,经过层层无聊的转化得到一个字符串而没有定义一个函数,也没有中间变量造成变量污染:

      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
                    People(11, 1, 30)
             .apply((val) {
              val.introduce = "我今年${val.age}${val.sex}${val.weight}";
            }).let((val) {
              if (val.sex == 1) return Monkey(11, 0, 30);
              return Monkey(11, 1, 30);
            }).let((val) {
              if (val.sex == 1) return "大猴子";
              return "程序猿";
            }).let((val) {
              return "整这么多干啥呢,好麻烦啊";
            })),
          ],
        ),
      ),

通过以上示例可以看出扩展函数是很有可玩性的,她能大大提高代码质量,让编程变得有趣,何不一起来探讨探讨呢?

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,732评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,496评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,264评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,807评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,806评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,675评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,029评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,683评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,704评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,666评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,773评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,413评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,016评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,204评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,083评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,503评论 2 343

推荐阅读更多精彩内容