Flutter数据不可变集合插件freezed_collection的使用
Flutter数据不可变集合插件freezed_collection的使用
freezed_collection
是一个扩展 freezed
的库,它提供了深度集合的 copyWith
功能。通过该库,你可以更方便地操作不可变的数据结构。
特性
✅ FreezedList<T>.fromJson
✅ FreezedList<T>.copyWith.replaceFirst(T newElement, bool Function(T element) what)
示例
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:freezed_collection/freezed_collection.dart';
part 'one.freezed.dart';
@freezed
class One with _$One {
const factory One(String name, Two two) = _One;
// 从JSON解析
factory One.fromJson(Map<String, dynamic> json) => _$OneFromJson(json);
}
@freezed
class Two with _$Two {
const factory Two(String name, FreezedList<Three> threes) = _Two;
// 从JSON解析
factory Two.fromJson(Map<String, dynamic> json) => _$TwoFromJson(json);
}
@freezed
class Three with _$Three {
const factory Three(String name) = _Three;
// 从JSON解析
factory Three.fromJson(Map<String, dynamic> json) => _$ThreeFromJson(json);
}
void test() {
// 初始化数据
final var1 = One('1', Two('2', FreezedList([Three('31'), Three('32'), Three('33')])));
final var2 = One('1', Two('2', FreezedList([Three('31'), Three('32'), Three('33')])));
final var21 = var2.copyWith();
// 比较var1与var2及var21
expect(var1, equals(var2));
expect(var1, equals(var21));
// 修改var21中的某些值
final var3 = var21.copyWith
.two(name: '21')
.copyWith
.two
.threes
.replaceFirst(Three('XXX'), (element) => element.name == '31');
// 验证修改后的结果
expect(var3, isNot(var21));
// 进一步修改var3
final var4 = var3.copyWith
.two(name: '2')
.copyWith
.two
.threes
.replaceFirst(Three('31'), (element) => element.name == 'XXX');
// 验证最终结果
expect(var4, equals(var21));
}
示例代码
import 'package:freezed_collection/freezed_collection.dart';
import 'dart:convert';
import 'assistant.dart';
import 'company.dart';
import 'director.dart';
// 打印公司信息
void printT<T>(T company) => print(json.encode(company));
void main() {
// 初始化公司对象
final company = Company(
name: '1',
director: Director(
name: 'director1',
assistants: FreezedList(
[Assistant(age: 1, name: '1'), Assistant(age: 3, name: '3')])));
// 将公司对象转换为JSON字符串,并重新解析
final jsonString = json.encode(company);
final restoredCompany = Company.fromJson(json.decode(jsonString));
// 打印恢复后的公司信息
print(restoredCompany);
// 创建新的公司对象,替换第一个年龄为1的助手
Company? newCompany = company.copyWith.director.assistants.replaceFirstWhere(
Assistant(age: 2, name: '2'),
(element) => element.age == 1,
);
// 创建另一个新的公司对象,替换第一个年龄为2的助手
Company? newCompany2 =
newCompany.copyWith.director.assistants.replaceFirstWhere(
Assistant(age: 1, name: '1'),
(element) => element.age == 2,
);
// 打印原始公司、新公司及其进一步修改后的公司
printT(company);
printT(newCompany);
printT(newCompany2);
// 验证新公司是否等于原始公司
print('Is newCompany equal to company? ${newCompany == company}');
print('Is newCompany equal to company? ${newCompany2 == company}');
}
更多关于Flutter数据不可变集合插件freezed_collection的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter数据不可变集合插件freezed_collection的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,下面是一个关于如何在Flutter项目中使用freezed_collection
插件来处理不可变集合的示例代码。freezed_collection
插件基于freezed
库,为Flutter开发者提供了不可变的List、Set和Map。
步骤 1: 添加依赖
首先,在你的pubspec.yaml
文件中添加freezed
和freezed_annotation
依赖:
dependencies:
flutter:
sdk: flutter
freezed_annotation: ^x.x.x # 使用最新版本号
dev_dependencies:
build_runner: ^x.x.x # 使用最新版本号
freezed: ^x.x.x # 使用最新版本号
步骤 2: 创建数据模型
接下来,创建一个数据模型并使用freezed
库来生成不可变类。同时,使用freezed_collection
来处理不可变的集合。
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:freezed_collection/freezed_collection.dart';
part 'model.freezed.dart';
@freezed
class User with _$User {
const factory User({
required String name,
required int age,
required List<String> hobbies,
required Set<String> skills,
required Map<String, String> addresses,
}) = _User;
factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
}
运行以下命令来生成freezed
代码:
flutter pub run build_runner build
步骤 3: 使用不可变集合
现在,你可以在你的Flutter应用中使用这个不可变的数据模型。以下是一个简单的示例,展示如何创建和修改一个User
对象:
void main() {
// 创建一个User对象
final user = User(
name: 'Alice',
age: 30,
hobbies: ['Reading', 'Hiking'],
skills: {'Dart', 'Flutter'},
addresses: {'Home': '123 Main St', 'Office': '456 Elm St'},
);
// 由于集合是不可变的,我们需要创建一个新的User对象来“修改”它
final updatedUser = user.copyWith(
hobbies: user.hobbies..add('Cycling'), // 注意:这里不能直接修改,只是演示意图
// 正确的方式是创建一个新的List
hobbies: [...user.hobbies, 'Cycling'],
skills: user.skills.union({'React'}).toSet(),
addresses: {
...user.addresses,
'Work': '789 Oak St',
},
);
// 打印原始用户和更新后的用户
print('Original User: $user');
print('Updated User: $updatedUser');
// 尝试直接修改会失败(编译时错误)
// user.hobbies.add('Swimming'); // 这行会报错,因为集合是不可变的
}
注意:在上面的代码中,尽管copyWith
方法被用来创建一个新的User
对象,但直接修改集合(如user.hobbies.add('Cycling')
)是错误的,这里只是为了说明意图。正确的方式是使用不可变集合的操作,如[...user.hobbies, 'Cycling']
来创建一个新的List。
结论
通过使用freezed
和freezed_collection
插件,你可以轻松地在Flutter应用中实现不可变的数据模型,从而提高应用的状态管理效率和可靠性。上述代码示例展示了如何定义和使用这些不可变集合,希望对你有所帮助。