在关联类型的实例上进行模式匹配的困难

时间:2015-12-24 18:55:33

标签: json pattern-matching rust deserialization type-mismatch

我依靠rustc_serialize将JSON数据解析为结构Orders,它代表VecOrder结构。 JSON数据可以具有数组或null值;我的意图是正常解析订单数组(如果有的话),或者将null值解析为Orders,空Vec。如果这两种情况都不是,那么就要传递错误。这是我的尝试:

impl Decodable for Orders {
    fn decode<D: Decoder>(d: &mut D) -> Result<Self, D::Error> {
        let try = d.read_seq(|d, l| {
            let mut orders = Vec::new();
            for _ in 0..l {
                let order = try!(Decodable::decode(d));
                orders.push(order);
            }
            Ok(Orders(orders))
        });

        match try {
            value @ Ok(_) => value,
            error @ Err(e) => match e {
                ExpectedError(_, x) if &x == "null" => Ok(Orders(Vec::new())),
                _ => error,
            },
        }
    } 
}

我的问题与ExpectedError上的模式匹配有关。编译器给出了以下错误:

 expected `<D as rustc_serialize::serialize::Decoder>::Error`,
    found `rustc_serialize::json::DecoderError`
(expected associated type,
    found enum `rustc_serialize::json::DecoderError`) [E0308]
src/api/types/json.rs:125                 ExpectedError(_, x) if &x == "null" => Ok(Orders(Vec::new())),
                                          ^~~~~~~~~~~~~~~~~~~

我对这个感到难过。我怎么能纠正这个?

1 个答案:

答案 0 :(得分:2)

  

我该如何纠正?

通常,您必须在通用或专业之间进行选择。您不能在关联类型上进行模式匹配,因为此类型可以是任何类型,并且泛型方法应该适用于满足约束的任何类型。

例如,在您的情况下:

  • <D as rustc_serialize::serialize::Decoder>::Error可以任何
  • rustc_serialize::json::DecoderError只是一种可能性

因此,您通常应该选择使用一些抽象的D或专门为json解码。

但是,由于您在此处实施Decodable,因此您不能选择不通用,因为您无法选择签名。

此外,似乎rustc_serialize不支持暂定解析(或者至少,它的json实现没有),所以我担心你无法检查无效(使用{{1} })事先。

我认为这些限制可以看作是这个图书馆退役的原因serde,并且只能鼓励你尝试一下。