从JSON强力输入Dart对象

时间:2014-03-21 16:32:57

标签: json dart

我正在学习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'.

然后是堆栈跟踪。因此,虽然可读性稍微好一些(文章的目标之一),但文章所承诺的强类型不起作用,代码可能会也可能不会崩溃,具体取决于输入。

我做错了什么?

2 个答案:

答案 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()中进行检查,这样它只能在检查模式下完成。我认为这将是一个很好的解决方案。