Dart 语言的高级玩法:Mixin, Extension, 泛型详解,写出优雅的 Flutter 代码
·

6.1 泛型 - 就像万能容器
// 泛型就像一个万能盒子,可以装任何类型的东西
class Box<T> {
T? _content;
void put(T item) {
_content = item;
print('放入了:$item');
}
T? get() {
print('取出了:$_content');
return _content;
}
bool get isEmpty => _content == null;
}
void genericExample() {
// 装字符串的盒子
var stringBox = Box<String>();
stringBox.put('Hello World');
String? message = stringBox.get();
// 装数字的盒子
var numberBox = Box<int>();
numberBox.put(42);
int? number = numberBox.get();
// 装任何东西的盒子
var flexibleBox = Box<dynamic>();
flexibleBox.put('文字');
flexibleBox.put(123);
}
// 泛型函数
T getFirst<T>(List<T> list) {
if (list.isEmpty) {
throw ArgumentError('列表不能为空');
}
return list.first;
}
void genericFunctionExample() {
List<String> names = ['Alice', 'Bob', 'Charlie'];
String firstName = getFirst(names); // 自动推断类型
List<int> numbers = [1, 2, 3];
int firstNumber = getFirst<int>(numbers); // 明确指定类型
}
6.2 扩展方法 - 就像给现有工具添加新功能
扩展方法让你可以给现有类添加新功能,而不需要修改原始代码。
🔧 基础扩展方法
// 给String类添加新功能
extension StringExtensions on String {
// 判断是否是邮箱
bool get isEmail {
return RegExp(r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$').hasMatch(this);
}
// 首字母大写
String get capitalize {
if (isEmpty) return this;
return this[0].toUpperCase() + substring(1).toLowerCase();
}
// 反转字符串
String get reverse {
return split('').reversed.join('');
}
// 移除所有空格
String get removeSpaces => replaceAll(' ', '');
// 判断是否是数字
bool get isNumeric => double.tryParse(this) != null;
// 截断字符串
String truncate(int maxLength, {String suffix = '...'}) {
if (length <= maxLength) return this;
return substring(0, maxLength - suffix.length) + suffix;
}
}
// 给List添加新功能
extension ListExtensions<T> on List<T> {
// 安全获取元素
T? safeGet(int index) {
if (index >= 0 && index < length) {
return this[index];
}
return null;
}
// 随机获取元素
T? get random {
if (isEmpty) return null;
return this[DateTime.now().millisecond % length];
}
// 分块处理
List<List<T>> chunk(int size) {
List<List<T>> chunks = [];
for (int i = 0; i < length; i += size) {
chunks.add(sublist(i, math.min(i + size, length)));
}
return chunks;
}
// 去重
List<T> get unique => toSet().toList();
// 计数
Map<T, int> get frequency {
Map<T, int> freq = {};
for (T item in this) {
freq[item] = (freq[item] ?? 0) + 1;
}
return freq;
}
}
⚡ 高级扩展技巧
// 给数字类型添加扩展
extension NumExtensions on num {
// 限制在范围内
num clamp(num min, num max) => math.max(min, math.min(max, this));
// 转换为百分比字符串
String get asPercentage => '${(this * 100).toStringAsFixed(1)}%';
// 判断是否在范围内
bool between(num min, num max) => this >= min && this <= max;
// 四舍五入到指定小数位
double roundTo(int decimals) {
double factor = math.pow(10, decimals).toDouble();
return (this * factor).round() / factor;
}
}
// 给DateTime添加扩展
extension DateTimeExtensions on DateTime {
// 是否是今天
bool get isToday {
DateTime now = DateTime.now();
return year == now.year && month == now.month && day == now.day;
}
// 是否是昨天
bool get isYesterday {
DateTime yesterday = DateTime.now().subtract(Duration(days: 1));
return year == yesterday.year && month == yesterday.month && day == yesterday.day;
}
// 友好的时间显示
String get timeAgo {
Duration diff = DateTime.now().difference(this);
if (diff.inDays > 0) return '${diff.inDays}天前';
if (diff.inHours > 0) return '${diff.inHours}小时前';
if (diff.inMinutes > 0) return '${diff.inMinutes}分钟前';
return '刚刚';
}
// 格式化为中文日期
String get chineseDate => '$year年$month月$day日';
}
// 给Map添加扩展
extension MapExtensions<K, V> on Map<K, V> {
// 安全获取值
V? safeGet(K key) => containsKey(key) ? this[key] : null;
// 过滤Map
Map<K, V> where(bool Function(K key, V value) test) {
Map<K, V> result = {};
forEach((key, value) {
if (test(key, value)) {
result[key] = value;
}
});
return result;
}
// 转换值
Map<K, R> mapValues<R>(R Function(V value) transform) {
Map<K, R> result = {};
forEach((key, value) {
result[key] = transform(value);
});
return result;
}
}
// 条件扩展 - 只对特定类型有效
extension IntExtensions on int {
// 判断是否是偶数
bool get isEven => this % 2 == 0;
// 判断是否是奇数
bool get isOdd => this % 2 != 0;
// 生成范围
List<int> to(int end) {
return List.generate(end - this + 1, (i) => this + i);
}
// 重复执行
void times(void Function(int index) action) {
for (int i = 0; i < this; i++) {
action(i);
}
}
}
// 可空类型的扩展
extension NullableStringExtensions on String? {
// 是否为空或null
bool get isNullOrEmpty => this == null || this!.isEmpty;
// 获取非空值或默认值
String orDefault(String defaultValue) => this ?? defaultValue;
// 安全调用
String? ifNotEmpty(String Function(String) action) {
if (this != null && this!.isNotEmpty) {
return action(this!);
}
return null;
}
}
🎯 实际应用示例
void extensionExample() {
// String扩展使用
String email = 'user@example.com';
print('是邮箱吗?${email.isEmail}'); // true
String name = 'john doe';
print('首字母大写:${name.capitalize}'); // John doe
String text = 'hello world';
print('反转:${text.reverse}'); // dlrow olleh
print('移除空格:${text.removeSpaces}'); // helloworld
print('截断:${text.truncate(8)}'); // hello...
// List扩展使用
List<String> fruits = ['苹果', '香蕉', '橙子', '苹果'];
print('安全获取:${fruits.safeGet(10)}'); // null
print('随机水果:${fruits.random}');
print('去重:${fruits.unique}'); // [苹果, 香蕉, 橙子]
print('分块:${fruits.chunk(2)}'); // [[苹果, 香蕉], [橙子, 苹果]]
// 数字扩展使用
double score = 0.856;
print('百分比:${score.asPercentage}'); // 85.6%
print('四舍五入:${score.roundTo(2)}'); // 0.86
int number = 42;
print('是偶数:${number.isEven}'); // true
print('范围:${3.to(7)}'); // [3, 4, 5, 6, 7]
// 重复执行
3.times((i) => print('第${i + 1}次'));
// DateTime扩展使用
DateTime now = DateTime.now();
print('是今天:${now.isToday}'); // true
print('中文日期:${now.chineseDate}');
DateTime past = now.subtract(Duration(hours: 2));
print('时间差:${past.timeAgo}'); // 2小时前
// 可空字符串扩展
String? nullableText;
print('是否为空:${nullableText.isNullOrEmpty}'); // true
print('默认值:${nullableText.orDefault('默认文本')}'); // 默认文本
}
如果文章对您有帮助,麻烦动动发财的小手点赞、关注和收藏,您的反馈将是作者不断更新的动力🙏🏻
更多推荐



所有评论(0)