我有以下Python代码:
def from_json(cls, data: dict, api: Optional[Overpass] = None) -> "Result":
"""
Create a new instance and load data from json object.
:param data: JSON data returned by the Overpass API
:param api:
:return: New instance of Result object
"""
result = cls(api=api)
elem_cls: Type[Union["Area", "Node", "Relation", "Way"]]
for elem_cls in [Node, Way, Relation, Area]:
for element in data.get("elements", []):
e_type = element.get("type")
if hasattr(e_type, "lower") and e_type.lower() == elem_cls._type_value:
result.append(elem_cls.from_json(element, result=result))
return result
我想把这个转换成Dart代码。这就是我想出来的:
factory Result.fromJson(Map<String, dynamic> data, {Overpass? api}) {
Result result = Result(api: api!);
Type elemCls;
for (elemCls in [Node, Way, Relation, Area]) {
for (Map<String, dynamic> element in data["elements"]) {
String eType = element["type"];
if (eType.toLowerCase() == elemCls.typeValue) {
result.append(elemCls.fromJson(element, result: result));
}
}
}
return result;
}
我的问题是The getter '_typeValue' isn't defined for the type 'Type'.
和The method 'fromJson' isn't defined for the type 'Type'.
。这是因为_typeValue
和fromJson
属于类Node
、Way
、Relation
和Area
,而不是Type
。我需要更改什么才能像Python那样工作呢?
发布于 2022-11-03 21:58:29
你可以做eType.toLowerCase() == elemCls.toString().toLowerCase()
。然而,elem_cls.from_json(element, result=result)
不能直接在Dart中完成。无法通用地用elemCls
类型实例化对象。
相反,您可以创建一个查找表,以便将类型名称映射到构造函数:
final _constructionTable = {
"node": Node.fromJson,
"way": Way.fromJson,
"relation": Relation.fromJson,
"area": Area.fromJson,
};
factory Result.fromJson(Map<String, dynamic> data, {Overpass? api}) {
Result result = Result(api: api!);
for (Map<String, dynamic> element in data["elements"]) {
String eType = element["type"]!;
var fromJson = _constructionTable[eType.toLowerCase()];
if (fromJson != null) {
result.append(fromJson(element, result: result));
}
}
return result;
}
请注意,这也会更有效,而且它避免了依赖为Dart类型生成的特定字符串。
https://stackoverflow.com/questions/74305227
复制相似问题