我在编写语言工具。我有一个languages.json文件,如下所示:
{
"paradigms": {
"test paradigm": {
"1sg": "me",
"2sg.gen": "lo",
"3pl.acc": "tven"
}
}
}(或至少这是相关的部分)
然后,在我的主省道文件中,我尝试打开JSON文件的一部分并将其解析成一个映射:
void main() async {
var langjson = jsonDecode(await File('resource/languages.json').readAsString());
var paradigms = Map<String, Map<String, String>>.from(langjson['paradigms']);
}现在达特告诉我_TypeError (type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'Map<String, String>')。好吧,我知道如果我不投它,那么paradigms无论如何都会是那种奇怪的类型,但是那样我就不能把它传递给某个类了,这意味着我必须让那些成员的类型也是动态的,而且看起来有点难看(我已经测试过了,它可以工作)。难道没有什么方法可以简单地从Map中获取jsonDecode吗?我以为它应该是这样运作的?
发布于 2020-07-22 14:26:14
_InternalLinkedHashMap 是Map的一个子类型,您可以在这个答案here中看到它。代码的问题是指定要存储在Map中的不兼容值。你说的是<String, String>,而它只能是<String, dynamic>。更改Map<String, Map<String, dynamic>>将解决您的问题。
此外,正如您在链接答案中所看到的,完全没有必要执行from构造函数来创建新的Map,因为jsonDecode已经返回了要创建的确切数据类型。
发布于 2020-07-23 07:17:36
解构JSON的静态返回类型是dynamic,因为它可以是映射、列表、数字、字符串、布尔或null。出于同样的原因,如果它是一个映射,那么它就是一个Map<String, dynamic>,因为这个值可能是上面的任何一个。
在您的例子中,您碰巧知道结果总是一个映射,并且该映射的值也是映射,而这些映射的值都是字符串。因此,数据将匹配一个Map<String, Map<String, String>>,但是JSON解码器不知道这一点,所以它构建了一个包含Map<String, dynamic>值的Map<String, dynamic>。
Dart重新表示泛型类型,因此只包含字符串的Map<String, dynamic>与Map<String, String>不一样。您可以将数字值添加到前者,而不是后者,因此它们是不同的。
要将数据映射转换为Map<String, String>类型的东西,您可以急切地这样做:
var paradigms = langJson["paradigms"].map(value: (k, v) => MapEntry(k, v as String));或者懒惰:
var paradigms = langJson["paradigms"].cast<String, String>();前者立即检查所有值,并创建一个新的map对象。后者包装原始map对象,并检查每个访问的值是否为String。
https://stackoverflow.com/questions/63035795
复制相似问题