Flutter模型生成插件im_model_gen的使用
Flutter 模型生成插件 im_model_gen 的使用
这个库提供了用于不可变模型的代码生成,包括值比较 ==
和 copyWith
方法。
项目目标:
- 标准语法。
- 在运行时之前捕获错误。
- 低源代码生成,你的IDE会很高兴。
- 改善输出二进制文件大小。
- 解锁继承(虽然鼓励每天使用组合,但“是-一个”模式也不错)。
- 不太侵入性。
要求
Dart SDK >= 3.6.0
使用
用 @ImModel
注解你的类
import 'package:im_model/im_model.dart';
part 'example.g.dart'; // 声明生成的部分文件
@ImModel()
class Example with _$ExampleMixin { // 关联你的类与生成的混入类
final String id;
final String? name;
final ImList<int> values; // ImList 是这个包的一部分。
const Example(this.id, {this.name, required this.values});
}
使用生成的类
const example = Example(id: 'id', values: ImList.empty());
// 复制
example.copyWith(text: 'test'); // Example(id: "id", text: test, values; [])
example.copyWith(text: null); // Example(id: "id", text: null, values: [])
// 相等性
const exampleTwo = Example(id: 'id', values: ImList.empty());
example == exampleTwo; // true
example == exampleTwo.copyWith(values: [1]); // false
// 不可变性
// example.values.add(1); // 'add' 未定义。
代码生成命令
dart run build_runner build --delete-conflicting-outputs
特性更多内容
有两个可用的注解。
@ImModel
可以应用于类,并具有以下参数:
ignoreCopy
: 允许忽略复制生成。默认为false
。ignoreEqual
: 允许忽略相等性生成。默认为false
。copyConstructor
: 如果需要,你可以设置一个命名构造函数用于复制生成。默认为null
。
@ImModel
可以应用于类字段以覆盖类注解,并具有以下参数:
ignoreCopy
: 允许忽略复制生成。默认为null
。ignoreEqual
: 允许忽略相等性生成。默认为null
。
集合
这个包通过简单地包装核心集合来提供不可变/可比较/可哈希的集合。
你必须将所有可变集合前缀为其不可变的对应物。
- List => ImList
- Map => ImMap
- Set => ImSet
代码生成器会在检测到可变集合时提供错误消息。
为了方便集合的修改,有两个获取器:
mut
=> 获取集合的可变版本。你可以免费使用它,只有当你修改它时才会复制该集合。immut
=> 获取集合的不可变版本。
查看下面的示例进行演示。
⚠️
- 显然,像其他地方一样,集合是不可变的,前提是元素也是不可变的。
- 目前,如果你使用自定义集合实现,该包将无法检测到。因此,像
MyFooList<int>
或ImList<MyFooList<int>>
这样的类型会被允许,但ImList<Set<int>>
或其他变体不会。
相等性
此包使用 Dart 3 记录使 ImModel
可比较。
此外,ImModel
强制同类型的模型之间的相等性。
现在,像 MyImModel() == Object()
这样的事情将在编译时触发错误。
最后,性能完全由 Dart 内部库确定,部分由 Im*
集合确定。
更高级的使用
现在我们已经了解了所有内容,这是一个完整的(花哨的)示例:
/// 类上的反转忽略标志 => 由字段覆盖
/// [id] 不是 `copyWith` 的一部分。
/// 只有 [id] 是相等性的部分。
@ImModel(ignoreEqual: true, ignoreCopy: true)
class Parent<T> with _$ParentMixin<T> {
@ImField(ignoreEqual: false)
final String id;
@ImField(ignoreCopy: false)
final T? aValue;
const Parent(this.id, this.aValue);
}
/// [collection] 类成员是不可变的(你不能使用 add、remove 等)。
/// [id] 不是 `copyWith` 的一部分。
/// 只有 [id] 和 [collection] 是相等性的部分。
@ImModel()
class Child<T> extends Parent<T> with _$ChildMixin<T> {
final ImList<int> collection;
const Child(super.id, super.aValue, {required this.collection});
}
void main() {
var obj1 = Child('a', 0, collection: [1].immut);
var obj2 = Child('a', 0, collection: ImList([1]));
// obj1 == obj2 => true
obj1 = obj1.copyWith(collection: obj1.collection.mut..add(2));
// obj1 == obj2 => false
// 注意两点:
// - 我们使用 `mut` 获取器来修改初始集合以获得更简洁的语法。
// - 我们不必再次包装集合使其成为不可变的,这是在生成的代码中完成的。
// obj1.copyWith(id: 'b');
// 名为 'id' 的命名参数未定义。
}
更多关于Flutter模型生成插件im_model_gen的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter模型生成插件im_model_gen的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是一个关于如何在Flutter项目中使用im_model_gen
插件的示例代码案例。im_model_gen
插件通常用于自动生成代码,特别是与即时通讯(IM)相关的数据模型。请注意,由于im_model_gen
并非一个广为人知的官方或广泛使用的Flutter插件,以下示例基于假设其工作原理类似于其他代码生成插件,如json_serializable
。
1. 添加依赖
首先,你需要在pubspec.yaml
文件中添加im_model_gen
依赖。假设该插件存在,且其配置如下:
dependencies:
flutter:
sdk: flutter
im_model_gen: ^x.y.z # 替换为实际版本号
dev_dependencies:
build_runner: ^x.y.z # 代码生成工具,通常需要最新版本
运行flutter pub get
来安装依赖。
2. 定义数据模型
创建一个数据模型文件,例如message_model.dart
,并定义你想要生成代码的类。假设im_model_gen
使用特定的注解来标记需要生成代码的类,类似于json_serializable
的@JsonSerializable()
注解。
import 'package:im_model_gen/im_model_gen.dart';
part 'message_model.g.dart'; // 生成的文件
@IMModel() // 假设这是im_model_gen的注解
class Message {
final String sender;
final String receiver;
final String content;
final DateTime timestamp;
Message({
required this.sender,
required this.receiver,
required this.content,
required this.timestamp,
});
// 通常,代码生成插件会生成fromJson和toJson方法
// 在这里,我们假设im_model_gen也会这样做
factory Message.fromJson(Map<String, dynamic> json) => _$MessageFromJson(json);
Map<String, dynamic> toJson() => _$MessageToJson(this);
}
3. 运行代码生成
在终端中运行以下命令来生成代码:
flutter pub run build_runner build
这将在你的项目目录下生成一个message_model.g.dart
文件,其中包含Message
类的fromJson
和toJson
方法的实现。
4. 使用生成的代码
现在你可以在你的Flutter应用中使用生成的代码了。例如,从JSON数据创建Message
对象,或者将Message
对象转换为JSON。
void main() {
// 示例JSON数据
String jsonData = '''
{
"sender": "Alice",
"receiver": "Bob",
"content": "Hello, Bob!",
"timestamp": "2023-10-05T14:48:00.000Z"
}
''';
// 将JSON数据解析为Message对象
Map<String, dynamic> jsonMap = jsonDecode(jsonData);
Message message = Message.fromJson(jsonMap);
// 打印Message对象的属性
print('Sender: ${message.sender}');
print('Receiver: ${message.receiver}');
print('Content: ${message.content}');
print('Timestamp: ${message.timestamp}');
// 将Message对象转换为JSON
Map<String, dynamic> jsonOutput = message.toJson();
print('JSON Output: $jsonOutput');
}
注意
- 由于
im_model_gen
并非一个已知的广泛使用的插件,上述代码和注解(如@IMModel()
)是基于假设的。实际使用时,你需要查阅im_model_gen
的官方文档来了解其具体的用法和注解。 - 如果
im_model_gen
插件不存在或功能不同,你可能需要寻找其他类似功能的插件,或者手动实现数据模型的序列化和反序列化。