Declaring expected variable type cause error: type '(Map<String, dynamic>) => University' is not a subtype of type '(dynamic) => dynamic' of 'f'
Declaring expected variable type cause error: type '(Map<String, dynamic>) => University' is not a subtype of type '(dynamic) => dynamic' of 'f'
我正在使用此逻辑将 json 数据转换为自定义 University 模型。
import 'dart:convert';
class UniversityWrapper {
UniversityWrapper({
this.isSuccess,
this.message,
this.data,
});
final bool isSuccess;
final dynamic message;
final List<University> data;
factory UniversityWrapper.fromRawJson(String str) => UniversityWrapper.fromJson(json.decode(str));
String toRawJson() => json.encode(toJson());
factory UniversityWrapper.fromJson(Map<String, dynamic> json) => UniversityWrapper(
isSuccess: json["is_success"],
message: json["message"],
data: json["data"] == null ? null : List<University>.from(json["data"].map((Map<String, dynamic> x) => University.fromJson(x))),
);
Map<String, dynamic> toJson() => <String, dynamic>{
"is_success": isSuccess,
"message": message,
"data": data == null ? null : List<dynamic>.from(data.map((University x) => x.toJson())),
};
}
class University {
University({
this.id,
this.name,
this.cityId,
});
final int id;
final String name;
final int cityId;
factory University.fromRawJson(String str) => University.fromJson(json.decode(str));
String toRawJson() => json.encode(toJson());
factory University.fromJson(Map<String, dynamic> json) => University(
id: json["id"],
name: json["name"],
cityId: json["city_id"],
);
Map<String, dynamic> toJson() => <String, dynamic>{
"id": id,
"name": name,
"city_id": cityId,
};
}
问题出在这一行:
data: json["data"] == null
? null
: List<University>.from(json["data"].map((Map<String, dynamic> x) => University.fromJson(x))),
如果我将 x 的类型设置为 dynamic 或 nothing,则没有不是错误。如示例 1 和 示例 2:
示例 1:
data: json["data"] == null
? null
: List<University>.from(json["data"].map((dynamic x) => University.fromJson(x))),
示例 2:
data: json["data"] == null
? null
: List<University>.from(json["data"].map((x) => University.fromJson(x))),
但主要问题是,我不明白为什么我不能将 Map 设置为 x[= 的类型47=]。我认为我应该能够设置它,因为 University.fromJson 方法需要 Map .
方法University.fromJson:
factory University.fromJson(Map<String, dynamic> json) => University(
id: json["id"],
name: json["name"],
cityId: json["city_id"],
);
错误:
E/flutter ( 4780): [ERROR:flutter/lib/ui/ui_dart_state.cc(199)] Unhandled Exception: type '(Map<String, dynamic>) => University' is not a subtype of type '(dynamic) => dynamic' of 'f'
E/flutter ( 4780): #0 new UniversityWrapper.fromJson (package:hb/models/university.dart:21:76)
E/flutter ( 4780): #1 _ProfilePageState.loadData (package:hb/ui/pages/profile.dart:118:66)
E/flutter ( 4780): <asynchronous suspension>
E/flutter ( 4780):
编辑 1: 示例 JSON 数据:
{
"is_success": true,
"message": null,
"data": [
{
"id": 1,
"name": "Abant İzzet Baysal Üniversitesi",
"city_id": 14
},
{
"id": 118,
"name": "Acıbadem Üniversitesi",
"city_id": 34
},
{
"id": 4,
"name": "Adıyaman Üniversitesi",
"city_id": 2
},
{
"id": 6,
"name": "Afyon Sağlık Bilimleri Üniversitesi",
"city_id": 3
}
]
}
reddit 上有人说:
I think because when you decode and parse JSON, it gives you a general
Dart object, not directly a map. So you have to cast it as a Map
afterwards.
Your fromJson method is expecting a Map<String, dynamic> argument, but
you are passing an object (the decoded JSON) which you labeled as
Map<String, dynamic>. I think it would work if you did
fromJson(x as Map<String,dynamic>)
instead of
fromJson(Map<String, dynamic> x)
dynamic or just "x" (which will be inferred as dynamic) works because
having a dynamic type could mean anything and removes the strict
checking
在Whosebug中有这样的解释:
In Dart, the element type of a list is provided when the list is
created, and it is kept as part of the list value. Every type you add
an element to the list, it is checked to be of that type. This is
unlike Java where generic type arguments are erased at runtime.
That means that a Dart List is not the same as a
List<Map<String, dynamic>>, even if both lists contains only instances
of Map<String, dynamic>>. For example, you can add an integer to the
former and not to the latter.
A JSON list can contain any JSON value. In this case, your list
contains only values that are maps, but that could be a coincidence.
The JSON parser does not check the source code first to see if the
list contains only one kind of objects, instead it just creates a
List and puts the elements into that. The created list is
mutable, so someone might add an integer to that list after it has
been returned. That code would break if the parser made the list a
List<Map<String, dynamic>> instead.
So, your list is a List because all JSON lists created by
jsonParse are that ... and it would be a breaking change to make them
anything else.
感谢您的回复。我的问题已经得到解答。我正在检查这个 post 作为正确答案。
我正在使用此逻辑将 json 数据转换为自定义 University 模型。
import 'dart:convert';
class UniversityWrapper {
UniversityWrapper({
this.isSuccess,
this.message,
this.data,
});
final bool isSuccess;
final dynamic message;
final List<University> data;
factory UniversityWrapper.fromRawJson(String str) => UniversityWrapper.fromJson(json.decode(str));
String toRawJson() => json.encode(toJson());
factory UniversityWrapper.fromJson(Map<String, dynamic> json) => UniversityWrapper(
isSuccess: json["is_success"],
message: json["message"],
data: json["data"] == null ? null : List<University>.from(json["data"].map((Map<String, dynamic> x) => University.fromJson(x))),
);
Map<String, dynamic> toJson() => <String, dynamic>{
"is_success": isSuccess,
"message": message,
"data": data == null ? null : List<dynamic>.from(data.map((University x) => x.toJson())),
};
}
class University {
University({
this.id,
this.name,
this.cityId,
});
final int id;
final String name;
final int cityId;
factory University.fromRawJson(String str) => University.fromJson(json.decode(str));
String toRawJson() => json.encode(toJson());
factory University.fromJson(Map<String, dynamic> json) => University(
id: json["id"],
name: json["name"],
cityId: json["city_id"],
);
Map<String, dynamic> toJson() => <String, dynamic>{
"id": id,
"name": name,
"city_id": cityId,
};
}
问题出在这一行:
data: json["data"] == null
? null
: List<University>.from(json["data"].map((Map<String, dynamic> x) => University.fromJson(x))),
如果我将 x 的类型设置为 dynamic 或 nothing,则没有不是错误。如示例 1 和 示例 2:
示例 1:
data: json["data"] == null
? null
: List<University>.from(json["data"].map((dynamic x) => University.fromJson(x))),
示例 2:
data: json["data"] == null
? null
: List<University>.from(json["data"].map((x) => University.fromJson(x))),
但主要问题是,我不明白为什么我不能将 Map
方法University.fromJson:
factory University.fromJson(Map<String, dynamic> json) => University(
id: json["id"],
name: json["name"],
cityId: json["city_id"],
);
错误:
E/flutter ( 4780): [ERROR:flutter/lib/ui/ui_dart_state.cc(199)] Unhandled Exception: type '(Map<String, dynamic>) => University' is not a subtype of type '(dynamic) => dynamic' of 'f'
E/flutter ( 4780): #0 new UniversityWrapper.fromJson (package:hb/models/university.dart:21:76)
E/flutter ( 4780): #1 _ProfilePageState.loadData (package:hb/ui/pages/profile.dart:118:66)
E/flutter ( 4780): <asynchronous suspension>
E/flutter ( 4780):
编辑 1: 示例 JSON 数据:
{
"is_success": true,
"message": null,
"data": [
{
"id": 1,
"name": "Abant İzzet Baysal Üniversitesi",
"city_id": 14
},
{
"id": 118,
"name": "Acıbadem Üniversitesi",
"city_id": 34
},
{
"id": 4,
"name": "Adıyaman Üniversitesi",
"city_id": 2
},
{
"id": 6,
"name": "Afyon Sağlık Bilimleri Üniversitesi",
"city_id": 3
}
]
}
reddit 上有人说:
I think because when you decode and parse JSON, it gives you a general Dart object, not directly a map. So you have to cast it as a Map afterwards.
Your fromJson method is expecting a Map<String, dynamic> argument, but you are passing an object (the decoded JSON) which you labeled as Map<String, dynamic>. I think it would work if you did
fromJson(x as Map<String,dynamic>)
instead of
fromJson(Map<String, dynamic> x)
dynamic or just "x" (which will be inferred as dynamic) works because having a dynamic type could mean anything and removes the strict checking
在Whosebug中有这样的解释:
In Dart, the element type of a list is provided when the list is created, and it is kept as part of the list value. Every type you add an element to the list, it is checked to be of that type. This is unlike Java where generic type arguments are erased at runtime.
That means that a Dart List is not the same as a List<Map<String, dynamic>>, even if both lists contains only instances of Map<String, dynamic>>. For example, you can add an integer to the former and not to the latter.
A JSON list can contain any JSON value. In this case, your list contains only values that are maps, but that could be a coincidence. The JSON parser does not check the source code first to see if the list contains only one kind of objects, instead it just creates a List and puts the elements into that. The created list is mutable, so someone might add an integer to that list after it has been returned. That code would break if the parser made the list a List<Map<String, dynamic>> instead.
So, your list is a List because all JSON lists created by jsonParse are that ... and it would be a breaking change to make them anything else.
感谢您的回复。我的问题已经得到解答。我正在检查这个 post 作为正确答案。