Flutter Dart中如何在Freezed模型里使用late final关键字?
问题原因
你给FbStory定义了const factory构造,Freezed会生成不可变的const实现类。而类体中late final Map<String, dynamic> data = jsonDecode(data_str);的初始化依赖jsonDecode这个非const运行时操作,这和const构造的核心要求(所有初始化逻辑必须是编译时常量)冲突,因此触发编译错误。
解决方案
根据你的需求,有两种可行方案:
方案1:移除const工厂构造(推荐,保留late final)
如果不需要创建const FbStory实例,直接去掉工厂构造的const关键字,让Freezed生成普通的不可变类,这样late final字段可以正常运行时初始化:
import 'dart:convert'; import 'package:freezed_annotation/freezed_annotation.dart'; part 'fb_story.freezed.dart'; part 'fb_story.g.dart'; @freezed class FbStory with _$FbStory { FbStory._(); // 去掉const关键字,改为普通工厂构造 factory FbStory({ required String id, required String data_str, @Default(false) bool imageNotAvailable, @Default(false) bool videoNotAvailable, String? imageUrl, String? videoUrl, }) = _FbStory; late final Map<String, dynamic> data = jsonDecode(data_str); factory FbStory.fromJson(Map<String, dynamic> json) => _$FbStoryFromJson(json); }
方案2:用缓存getter替代late final(保留const构造)
如果需要保留const factory构造,将data改为带缓存的getter,既实现延迟加载,又符合const类的要求:
import 'dart:convert'; import 'package:freezed_annotation/freezed_annotation.dart'; part 'fb_story.freezed.dart'; part 'fb_story.g.dart'; @freezed class FbStory with _$FbStory { FbStory._(); const factory FbStory({ required String id, required String data_str, @Default(false) bool imageNotAvailable, @Default(false) bool videoNotAvailable, String? imageUrl, String? videoUrl, }) = _FbStory; // 私有late final字段缓存解码结果 late final Map<String, dynamic> _cachedData = jsonDecode(data_str); // 对外暴露getter,第一次访问时触发解码 Map<String, dynamic> get data => _cachedData; factory FbStory.fromJson(Map<String, dynamic> json) => _$FbStoryFromJson(json); }
注意:使用此方案时,不能通过
const FbStory(...)创建实例后立即在const上下文里访问data,因为jsonDecode是运行时操作,会破坏const实例的不可变性。
关于Freezed的@late注解
早期Freezed版本的@late注解用于生成延迟加载字段,但目前已推荐直接使用Dart原生的late final结合上述方案实现。如果一定要用旧版的@late,需要确保你的Freezed版本兼容,且用法为在类体中标记getter:
// 旧版Freezed用法(不推荐,已被原生late替代) @late Map<String, dynamic> get data => jsonDecode(data_str);
内容的提问来源于stack exchange,提问作者TSR
相关产品推荐
相关产品推荐

