2014-06-27 18 views
1

将Rust描述为测试驱动器。目前为止有趣,但我不确定如何在这个实例中设置特征边界来做一些有用的事情。Enum和Structs上的可编码特性边界的问题

Failed to find an implementation of trait serialize::serialize::Encodable,std::io::IoError> for T

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

error: trait bounds are not allowed in enumeration definitions

所以我认为我将不得不把边界上实现impl<T:Encodable>,但得到这个...

error: wrong number of type arguments: expected 2 but found 0

如果是这样的话,我将如何做这样的事情在鲁斯特?

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); 

回答

4

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

我们来看看特征的定义:Encodable<S: Encoder<E>, E>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> { 
     … 
    } 
}