英文:
How to use late final keyword in Flutter Dart freezed model?
问题
在Flutter Dart的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);
}
错误:
Error: A constant constructor can't call a non-constant super constructor.
在以前,Freezed使用@late
注解来引入late
关键字,所以我猜应该有一种方法可以使这个工作。该类仍然被freezed修饰,只是变成了懒加载。
英文:
How to use late final keyword in Flutter Dart freezed model ?
This code generates successfully and has no static analysis error but it does not compile strangely.
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);
}
Error:
Error: A constant constructor can't call a non-constant super constructor.
Before, Freezed used to pioneer the late
keyword with @late
annotation so I guess there should be a way to make this work. class is still freezed, just lazy
答案1
得分: 1
错误非常明确,您不能在带有late
变量的情况下拥有const
构造函数。这不是freezed的错误,普通的Dart类也会出现这个错误:
class FbStory {
const FbStory(this.data_str);
final String data_str;
// 无法定义'const'构造函数,因为字段'data'被初始化为非常量值。
late final Map<String, dynamic> data = jsonDecode(data_str);
}
要解决此问题,我建议从const factory FbStory(...)
中删除const
。
或者,您可以创建一个由json_serializable提供的转换器类:
class StringToMapConverter implements JsonConverter<Map<String, dynamic>, String> {
const StringToMapConverter();
@override
Map<String, dynamic> fromJson(String json) {
return jsonDecode(json) as Map<String, dynamic>;
}
@override
String toJson(Map<String, dynamic> object) {
return jsonEncode(object);
}
}
然后,您的类FbStory
将如下所示:
@freezed
class FbStory with _$FbStory {
FbStory._();
const factory FbStory({
required String id,
@JsonKey(name: 'data_str')
@StringToMapConverter()
required Map<String, dynamic> data,
@Default(false) bool imageNotAvailable,
@Default(false) bool videoNotAvailable,
String? imageUrl,
String? videoUrl,
}) = _FbStory;
英文:
The error is quite explicit, you cannot have a const
constructor with a late
variable. This is not an error with freezed, a normal Dart class will also have this error:
class FbStory {
const FbStory(this.data_str);
final String data_str;
// Can't define the 'const' constructor because the field 'data'
// is initialized with a non-constant value.
late final Map<String, dynamic> data = jsonDecode(data_str);
}
To fix your issue I would recommend to remove the const
from your const factory FbStory(...)
.
Or you could create a converter class provided by json_serializable:
class StringToMapConverter implements JsonConverter<Map<String, dynamic>, String> {
const StringToMapConverter();
@override
Map<String, dynamic> fromJson(String json) {
return jsonDecode(json) as Map<String, dynamic>;
}
@override
String toJson(Map<String, dynamic> object) {
return jsonEncode(object);
}
}
Your class FbStory
would then look like this:
@freezed
class FbStory with _$FbStory {
FbStory._();
const factory FbStory({
required String id,
@JsonKey(name: 'data_str')
@StringToMapConverter()
required Map<String, dynamic> data,
@Default(false) bool imageNotAvailable,
@Default(false) bool videoNotAvailable,
String? imageUrl,
String? videoUrl,
}) = _FbStory;
答案2
得分: -1
只需在factory FbStory
上删除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._();
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);
}
英文:
Just remove const at factory FbStory
Full code:
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._();
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);
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论