【问题标题】:Trouble with Encodable Trait Bounds on Enums and Structs枚举和结构上的可编码特征边界问题
【发布时间】:2014-06-27 04:05:34
【问题描述】:

以 Rust 进行试驾。到目前为止很有趣,但我不确定如何在这种情况下设置特征界限来做一些有用的事情。

未能找到 trait 的实现 serialize::serialize::Encodable,std::io::IoError> 为T

在我看来,我需要对枚举 List<T: Encodable> 设置一个界限。但是,当我尝试这个时,编译器会有点不高兴。

错误:枚举中不允许​​特征边界 定义

所以我认为我必须限制实现impl<T:Encodable>,但得到了这个......

错误:类型参数的数量错误:预期为 2,但 找到 0

如果是这样,我将如何在 Rust 中做这样的事情?

extern crate serialize;
use serialize::{ json, Encodable };

#[deriving(Decodable, Encodable)] 
pub enum List<T> {
    Node(T, Box<List<T>>),
    Nil
}

impl<T> List<T> {
fn to_json(&self) -> String {
    json::Encoder::str_encode(self)
}
}

当我工作时似乎工作正常不要尝试封装编码,因为它知道 int 是可编码的......

let mut list: List<int> = Nil;
...
let encoded_string = json::Encoder::str_encode(&list);
println!("{}", encoded_string);

【问题讨论】:

    标签: rust


    【解决方案1】:

    目前,不能在结构和枚举上放置边界。这可能会改变,但在那之前,impl 是您定义这些约束的地方。

    我们来看看 trait 的定义:Encodable&lt;S: Encoder&lt;E&gt;, E&gt;SE 是它抱怨的东西,希望你定义它们。

    现在让我们看看#[deriving(Encodable)] 做了什么,用rustc --pretty expanded 编译代码,扩展了该属性。

    #![feature(phase)]
    #![no_std]
    #![feature(globs)]
    #[phase(plugin, link)]
    extern crate std = "std#0.11.0-pre";
    extern crate native = "native#0.11.0-pre";
    extern crate serialize;
    use std::prelude::*;
    use serialize::{json, Encodable};
    
    pub enum List<T> { Node(T, Box<List<T>>), Nil, }
    #[automatically_derived]
    impl <__S: ::serialize::Encoder<__E>, __E,
          T: ::serialize::Encodable<__S, __E>> ::serialize::Encodable<__S, __E>
         for List<T> {
        fn encode(&self, __arg_0: &mut __S) -> ::std::result::Result<(), __E> {
            match *self {
                Node(ref __self_0, ref __self_1) => {
                    let _e = __arg_0;
                    _e.emit_enum("List",
                                 |_e|
                                     _e.emit_enum_variant("Node", 0u, 2u, |_e| {
                                                          match _e.emit_enum_variant_arg(0u,
                                                                                         |_e|
                                                                                             (*__self_0).encode(_e))
                                                              {
                                                              Ok(__try_var) =>
                                                              __try_var,
                                                              Err(__try_var) =>
                                                              return Err(__try_var)
                                                          };
                                                          return _e.emit_enum_variant_arg(1u,
                                                                                          |_e|
                                                                                              (*__self_1).encode(_e));
                                                      }))
                },
                Nil => {
                    let _e = __arg_0;
                    _e.emit_enum("List",
                                 |_e|
                                     _e.emit_enum_variant("Nil", 1u, 0u, |_e| {
                                                          return ::std::result::Ok(());
                                                      }))
                }
            }
        }
    }
    #[automatically_derived]
    impl <__D: ::serialize::Decoder<__E>, __E,
          T: ::serialize::Decodable<__D, __E>> ::serialize::Decodable<__D, __E>
         for List<T> {
        fn decode(__arg_0: &mut __D) -> ::std::result::Result<List<T>, __E> {
            __arg_0.read_enum("List",
                              |_d|
                                  _d.read_enum_variant(["Node", "Nil"],
                                                       |_d, i|
                                                           ::std::result::Ok(match i
                                                                                 {
                                                                                 0u
                                                                                 =>
                                                                                 Node(match _d.read_enum_variant_arg(0u,
                                                                                                                     |_d|
                                                                                                                         ::serialize::Decodable::decode(_d))
                                                                                          {
                                                                                          Ok(__try_var)
                                                                                          =>
                                                                                          __try_var,
                                                                                          Err(__try_var)
                                                                                          =>
                                                                                          return Err(__try_var)
                                                                                      },
                                                                                      match _d.read_enum_variant_arg(1u,
                                                                                                                     |_d|
                                                                                                                         ::serialize::Decodable::decode(_d))
                                                                                          {
                                                                                          Ok(__try_var)
                                                                                          =>
                                                                                          __try_var,
                                                                                          Err(__try_var)
                                                                                          =>
                                                                                          return Err(__try_var)
                                                                                      }),
                                                                                 1u
                                                                                 =>
                                                                                 Nil,
                                                                                 _
                                                                                 =>
                                                                                 ::std::rt::begin_unwind("internal error: entered unreachable code",
                                                                                                         "s.rs",
                                                                                                         4u)
                                                                             })))
        }
    }
    
    impl <T> List<T> {
        fn to_json(&self) -> String { json::Encoder::str_encode(self) }
    }
    

    是的,这很混乱。但它显示了Encodable 实现和正在编写的边界。基本上,约束应该由您以相同的方式编写:您不关心任何 特定 类型,只关心您有一个编码器。那么,这就是它归结为:

    impl<S: Encoder<E>, E, T: Encodable<S, E>> Encodable<S, E> for List<T> {
        fn encode(&self, encoder: &mut S) -> Result<(), E> {
            …
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-13
      • 1970-01-01
      • 2018-11-23
      • 1970-01-01
      • 1970-01-01
      • 2016-11-29
      • 1970-01-01
      • 2018-12-18
      相关资源
      最近更新 更多