我正在学习Dart并正在阅读文章Using Dart with JSON Web Services,该文章告诉我,在将对象转换为JSON和从JSON转换时,我可以获得类型检查方面的帮助。我使用了他们的代码片段,但最终得到了编译器警告。我发现another Stack Overflow question讨论了同样的问题,答案是使用@proxy
注释并实现noSuchMethod
。这是我的尝试:
abstract class Language {
String language;
List targets;
Map website;
}
@proxy
class LanguageImpl extends JsonObject implements Language {
LanguageImpl();
factory LanguageImpl.fromJsonString(string) {
return new JsonObject.fromJsonString(string, new LanguageImpl());
}
noSuchMethod(i) => super.noSuchMethod(i);
}
我不知道noSuchMethod
实施是否正确,@proxy
现在看似多余。无论如何,代码没有做我想要的。如果我跑
var lang1 = new LanguageImpl.fromJsonString('{"language":"Dart"}');
print(JSON.encode(lang1));
print(lang1.language);
print(lang1.language + "!");
var lang2 = new LanguageImpl.fromJsonString('{"language":13.37000}');
print(JSON.encode(lang2));
print(lang2.language);
print(lang2.language + "!");
我得到了输出
{"language":"Dart"}
Dart
Dart!
{"language":13.37}
13.37
type 'String' is not a subtype of type 'num' of 'other'.
然后是堆栈跟踪。因此,虽然可读性稍微好一些(文章的目标之一),但文章所承诺的强类型不起作用,代码可能会也可能不会崩溃,具体取决于输入。
我做错了什么?
答案 0 :(得分:0)
文章提到了一个段落中的静态类型,但JsonObject与静态类型无关
你从JsonObject得到的是你不需要Map访问语法
您可以编写someMap['language'] = value;
而不是someObj.language = value;
来获取自动完成列表中的字段,但是当您为对象的字段赋值时,Dart也无法进行任何类型检查({{ 1}})当你使用someObj.language = value;
时(因为noSuchMethod / @ proxy而提到)。
答案 1 :(得分:0)
我假设您希望在此行上抛出异常:
var lang2 = new LanguageImpl.fromJsonString('{"language":13.37000}');
因为13.37不是String。为了让JsonObject执行此操作,需要使用镜像来确定字段的类型并手动进行类型检查。这是可能的,但它会添加到dart2js输出大小。
因此,我认为在阅读字段时抛出类型错误是合理的,您可能刚刚发现了一个有价值的问题。由于noSuchMethod用于实现抽象方法,因此运行时实际上可以对参数进行类型检查并返回值。从你的例子看来,它不是。小心提交错误?
如果这个被解决了,那么JsonObject可以在设置它之后立即读取一个字段,以便在没有镜像的情况下进行解码时进行类型检查,并且可以在assert()中进行检查,这样它只能在检查模式下完成。我认为这将是一个很好的解决方案。