我有一個要保存到本地存盤的物件,但是每當我將該物件寫入存盤時,我都會收到標題中顯示的錯誤。
這是完整的堆疊跟蹤
[VERBOSE-2:ui_dart_state.cc(198)] Unhandled Exception: type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'Map<String, double>' in type cast
#0 new Product.fromJson (package:app/src/objects/product.dart:27:47)
#1 new ShoppingListProduct.fromJson (package:app/src/objects/shopping_list_product.dart:18:29)
#2 ShoppingListHandler.readShoppingListProducts.<anonymous closure> (package:app/src/handlers/shopping_list_handler.dart:65:38)
#3 MappedListIterable.elementAt (dart:_internal/iterable.dart:413:31)
#4 ListIterator.moveNext (dart:_internal/iterable.dart:342:26)
#5 new _GrowableList._ofEfficientLengthIterable (dart:core-patch/growable_array.dart:189:27)
#6 new _GrowableList.of (dart:core-patch/growable_array.dart:150:28)
#7 new List.of (dart:core-patch/array_patch.dart:51:28)
這是用于寫入、讀取和更新 shoppingListProduct 類的處理程式類。
class ShoppingListHandler {
ShoppingListHandler._privateConstructor();
static final ShoppingListHandler instance = ShoppingListHandler._privateConstructor();
static File? _file;
static const _fileName = 'shopping_list_file.txt';
// Get the data file
Future<File> get file async {
if (_file != null) return _file!;
_file = await _initFile();
return _file!;
}
// Initialize file
Future<File> _initFile() async {
final _directory = await getApplicationDocumentsDirectory();
final _path = _directory.path;
// Check if file exists
File file = File('$_path/$_fileName');
if(await file.exists() == false){
await file.create(recursive: true);
}
return file;
}
// Users
static Set<ShoppingListProduct> _shoppingListSet = {};
Future<void> writeShoppingList(ShoppingListProduct shoppingListProduct) async {
final File fl = await file;
_shoppingListSet.add(shoppingListProduct);
// Now convert the set to a list as the jsonEncoder cannot encode
// a set but a list.
final _shoppingListMap = _shoppingListSet.map((e) => e.toJson()).toList();
await fl.writeAsString(jsonEncode(_shoppingListMap));
}
Future<List<ShoppingListProduct>> readShoppingListProducts() async {
final File fl = await file;
final _content = await fl.readAsString();
List<dynamic> _jsonData = [];
if(_content.isNotEmpty){
_jsonData = jsonDecode(_content);
}
final List<ShoppingListProduct> _shoppingListProducts = _jsonData
.map(
(e) => ShoppingListProduct.fromJson(e as Map<String, dynamic>),
)
.toList();
return _shoppingListProducts;
}
Future<void> deleteShoppingListProduct(ShoppingListProduct shoppingListProduct) async {
final File fl = await file;
_shoppingListSet.removeWhere((e) => e == shoppingListProduct);
final _shoppingListMap = _shoppingListSet.map((e) => e.toJson()).toList();
await fl.writeAsString(jsonEncode(_shoppingListMap));
}
Future<void> updateShoppingListProduct({
required String key,
required ShoppingListProduct updatedShoppingListProduct,
}) async {
_shoppingListSet.removeWhere((e) => e.ID == updatedShoppingListProduct.ID);
await writeShoppingList(updatedShoppingListProduct);
}
}
shoppingListProduct 類只有 3 個引數。一個 ID,它只是一個整數。Product 引數,它是 Product 類中的 Product 物件。和一個勾選的布林值。
我相信問題是在 Product 類中我有一個“價格”物件,它是一個帶有字串和雙精度的映射。這是產品類別。
class Product extends Equatable{
const Product({
required this.user,
required this.id,
required this.name,
required this.image,
required this.brandName,
required this.productPrices,
});
final String user;
final int id;
final String name;
final String image;
final String brandName;
final Map<String, double> productPrices;
Product.fromJson(Map<String, dynamic> map)
: user = (map['user'] as String),
id = (map['id'] as int ).toInt(),
name = (map['name'] as String),
image = (map['image'] as String),
brandName = (map['brandName'] as String),
productPrices = (map['productPrices'] as Map<String, double>);
Map<String, dynamic> toJson(){
return {
'user': user,
'id': id,
'name': name,
'image': image,
'brandName': brandName,
'productPrices': productPrices,
};
}
@override
String toString(){
return 'Product:\n\tId: $id\n\tName: $name\n\tImage: $image\n\tBrandName: $brandName\n\tProductPrices: $productPrices';
}
@override
List<Object> get props => [id, name, image, brandName, productPrices];
}
這是在保存程序中使用的 shoppingListProduct 類。
class ShoppingListProduct extends Equatable {
ShoppingListProduct({
required this.ID,
required this.product,
required this.ticked,
});
final int ID;
final Product product;
late bool ticked;
ShoppingListProduct.fromJson(Map<String, dynamic> map)
: ID = (map['ID'] as int).toInt(),
product = Product.fromJson(map['product']),
ticked = (map['ticked'] as bool);
Map<String, dynamic> toJson() {
return {
'ID': ID,
'product': product,
'ticked': ticked,
};
}
@override
String toString() {
return 'ShoppingListProduct:\n\tID: $ID\n\tProduct: $product\n\tTicked: $ticked';
}
@override
List<Object> get props => [ID, product, ticked];
}
uj5u.com熱心網友回復:
在 Dart 中,型別引數在運行時被保留,并在型別檢查期間被考慮。所以 aMap<String, dynamic>不是的子型別Map<String, double>也不能轉換為它,這是您在此處看到的錯誤。
由于 Dart 中的 JSON 決議器無法事先知道映射的正確型別,因此所有 JSON 物件都被決議為Map<String, dynamic>. 由于您確定地圖將僅包含雙精度值,因此您可以(map['productPrices'] as Map<String, dynamic>).cast<String, double>()在fromJson建構式中使用。
map 上的cast方法將回傳原始地圖的視圖。此視圖將在查找期間進行強制轉換,而不是針對您使用操作員所做的整個地圖as。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/497268.html
下一篇:共享偏好:值未實時或立即更新
