将可变长度JSON数组解码为Rust数组

时间:2015-12-15 19:57:05

标签: json serialization rust

我试图解码这些数据:

{
  "ok": true,
  "people": [
    {
      "name": "John",
      "age": "10"
    }
  ]
}

进入结构。代码是:

extern crate rustc_serialize;

use rustc_serialize::json;

#[derive(RustcDecodable)]
struct Man {
    name: String,
    age: i32,
}

#[derive(RustcDecodable)]
struct Men {
    ok:      bool,
    people: [Man; 16],
}

...

let json: Men = json::decode(&data).unwrap();

...

问题是当Men中数组的长度与JSON中相应字段的长度完全匹配时,会发生以下错误:

thread '<main>' panicked at 'called `Result::unwrap()`
on an `Err` value: ApplicationError("wrong array length")',
../src/libcore/result.rs:738

有关如何处理此事的任何想法? 也欢迎一般代码风格的建议。

2 个答案:

答案 0 :(得分:6)

拥有一个仅部分填充的数组并没有多大意义。数组静态地确切知道要分配多少空间,但是您必须使用某些来填充该空间,以避免未初始化数据的某些安全问题。他们没有“未使用”的概念。

最简单的解决方法是使用Vec

#[derive(RustcDecodable)]
struct Men {
    ok:     bool,
    people: Vec<Man>,
}

Vec表示可调整大小连续数据量。它知道分配了多少空间这些分配中有多少是有效的,并且永远不会让您访问无效项目。

答案 1 :(得分:4)

嗯,要么你真的只有长度为1的男性名单,那么你可以将类型改为people: [Man; 1]。或者您实际上在运行时具有可变长度,在这种情况下,您最好选择动态大小的矢量,例如people: Vec<Man>

作为提示:serdeserde_json可能是更好的选择作为依赖关系,因为rustc-serialize仅从编译器中提取,因此它不必最终在{{ 1}}永久。