flutter中 extension类方法拓展

本文同步发表于我的微信公众号,微信搜索 程语新视界 即可关注,每个工作日都有文章更新

一、扩展的基本语法

1.1 基本定义

extension <ExtensionName> on <Type> {
  // 方法、getter、setter、操作符等
}

1.2 示例:为 String 添加新功能

extension StringEnhancements on String {
  // 添加一个反转字符串的方法
  String get reversed {
    return split('').reversed.join();
  }
  
  // 添加判断是否为有效邮箱方法
  bool get isValidEmail {
    final regex = RegExp(r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$');
    return regex.hasMatch(this);
  }
}

void main() {
  String text = 'hello';
  print(text.reversed); // 输出: olleh
  
  String email = 'user@example.com';
  print(email.isValidEmail); // 输出: true
}

二、扩展的不同类型

2.1 实例方法扩展

extension NumberFormatters on int {
  // 将数字格式化为带千位分隔符的字符串
  String formatWithCommas() {
    final numberStr = toString();
    final result = StringBuffer();
    
    for (int i = 0; i < numberStr.length; i++) {
      if (i > 0 && (numberStr.length - i) % 3 == 0) {
        result.write(',');
      }
      result.write(numberStr[i]);
    }
    
    return result.toString();
  }
}

void main() {
  int price = 1234567;
  print(price.formatWithCommas()); // 输出: 1,234,567
}

2.2 Getter 扩展

extension DateTimeHelpers on DateTime {
  // 判断日期是否为今天
  bool get isToday {
    final now = DateTime.now();
    return year == now.year && month == now.month && day == now.day;
  }
  
  // 获取该日期的开始时间(00:00:00)
  DateTime get startOfDay {
    return DateTime(year, month, day);
  }
}

void main() {
  DateTime today = DateTime.now();
  DateTime tomorrow = today.add(const Duration(days: 1));
  
  print(today.isToday); // 输出: true
  print(tomorrow.isToday); // 输出: false
  print(today.startOfDay); // 输出: 2024-01-15 00:00:00.000
}

2.3 操作符扩展

extension ListOperations<T> on List<T> {
  // 自定义操作符:列表相乘(重复n次)
  List<T> operator *(int times) {
    if (times <= 0) return [];
    
    final result = <T>[];
    for (int i = 0; i < times; i++) {
      result.addAll(this);
    }
    return result;
  }
}

void main() {
  List<int> numbers = [1, 2, 3];
  List<int> repeated = numbers * 3;
  print(repeated); // 输出: [1, 2, 3, 1, 2, 3, 1, 2, 3]
}

三、泛型扩展

extension CollectionUtils<T> on List<T> {
  // 安全地获取元素,索引越界时返回null
  T? getSafe(int index) {
    if (index >= 0 && index < length) {
      return this[index];
    }
    return null;
  }
  
  // 将列表分成指定大小的块
  List<List<T>> chunk(int size) {
    if (size <= 0) return [];
    
    final chunks = <List<T>>[];
    for (int i = 0; i < length; i += size) {
      final end = (i + size) < length ? (i + size) : length;
      chunks.add(sublist(i, end));
    }
    return chunks;
  }
}

void main() {
  List<String> fruits = ['apple', 'banana', 'orange', 'grape', 'mango'];
  
  print(fruits.getSafe(10)); // 输出: null
  print(fruits.getSafe(2));  // 输出: orange
  
  List<List<String>> chunks = fruits.chunk(2);
  print(chunks); // 输出: [[apple, banana], [orange, grape], [mango]]
}

四、扩展的命名和冲突解决

4.1 命名扩展

// 为同一类型创建多个扩展时使用命名
extension StringValidators on String {
  bool get isStrongPassword {
    return length >= 8 && 
           contains(RegExp(r'[A-Z]')) && 
           contains(RegExp(r'[0-9]'));
  }
}

extension StringFormatters on String {
  String get capitalizeFirst {
    if (isEmpty) return this;
    return this[0].toUpperCase() + substring(1).toLowerCase();
  }
}

void main() {
  String password = 'Password123';
  print(password.isStrongPassword); // 输出: true
  
  String name = 'dart language';
  print(name.capitalizeFirst); // 输出: Dart language
}

4.2 处理扩展冲突

当多个扩展有相同名称的成员时,可以使用显式语法:

extension TextUtils on String {
  String truncate(int maxLength) {
    if (length <= maxLength) return this;
    return '${substring(0, maxLength)}...';
  }
}

extension StringManipulation on String {
  String truncate(int maxLength, {String suffix = '***'}) {
    if (length <= maxLength) return this;
    return '${substring(0, maxLength)}$suffix';
  }
}

void main() {
  String longText = '这是一个很长的文本需要截断显示';
  
  // 使用显式语法解决冲突
  print(TextUtils(longText).truncate(5)); // 输出: 这是一个很...
  print(StringManipulation(longText).truncate(5, suffix: '>>>')); // 输出: 这是一个很>>>
}

五、扩展的限制

  1. 不能添加实例变量

  2. 不能访问类的私有成员

  3. 不能覆盖已有的方法

  4. 扩展方法是静态解析的(在编译时确定)

  5. 扩展名是可选的,但推荐使用以提高可读性

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值