我有一个小程序,用这个结构操作一些JSON数据:
{
"categories": [{
"id": 0,
"title": "cat1"
}],
"drinks": [{
"categoryId": 0,
"image": "image",
"title": "title",
"text": "text"
}]
}
如果我使用动态类型或var关键字编码,一切都很好,但是当我声明类型时,我收到以下错误。
'List<dynamic>' is not a subtype of type 'List<Map<String, dynamic>>'
。
这是该计划:
import 'dart:convert';
main(List<String> args) {
String source = ''' {
"categories": [{
"id": 0,
"title": "cat1"
}],
"drinks": [{
"categoryId": 0,
"image": "image",
"title": "title",
"text": "text"
}]
}''';
var json = jsonDecode(source);
// Dynamic types, works ok!
var categories = json['categories'];
var title = categories[0]['title'];
var id = categories[0]['id'];
print('$title with $id');
// Explicit types, error!
List<Map<String,dynamic>> categories2 = json['categories'];
String title2 = categories2[0]['title'];
int id2 = categories2[0]['id'];
print('$title2 with $id2');
}
为什么我收到此错误? categories
是List<dynamic>
类型,但为什么它不是List<Map<String,dynamic>>
?
在Dart中,列表的元素类型在创建列表时提供,并作为列表值的一部分保留。您向列表添加元素的每种类型都会被检查为该类型。这与Java不同,在运行时擦除泛型类型参数。
这意味着Dart List<dynamic>
与List<Map<String, dynamic>>
不同,即使两个列表仅包含Map<String, dynamic>>
的实例。例如,您可以向前者添加整数,而不是向后者添加整数。
JSON列表可以包含任何JSON值。在这种情况下,您的列表仅包含地图的值,但这可能是巧合。 JSON解析器不会首先检查源代码以查看列表是否只包含一种对象,而只是创建一个List<dynamic>
并将元素放入其中。创建的列表是可变的,因此有人可能会在返回后将该整数添加到该列表中。如果解析器使列表成为List<Map<String, dynamic>>
,那么代码将会中断。
所以,你的列表是一个List<dynamic>
,因为jsonParse
创建的所有JSON列表都是......并且它将是一个突破性的变化,使它们成为别的东西。