我有一个匹配表达式,可以返回几个(内置和自定义)类型,最终将序列化为JSON并从Web请求返回。我宁愿避免重复序列化代码或在每个匹配组中制作字符串副本。
每只手臂返回Encodable
;但是,似乎Encodable
不是对象安全的,所以我无法指向它。
编辑:由于Rust的变化,问题已经从"这是一个很好的方法吗?"到"我怎么能这样做?" (这是版本rustc 1.0.0-nightly (ed530d7a3 2015-01-16 22:41:16 +0000)
)
extern crate "rustc-serialize" as rustc_serialize;
use rustc_serialize::{json, Encodable};
#[derive(RustcEncodable)]
struct Valid {
value: u32
}
#[derive(RustcEncodable)]
struct Error {
error: &'static str // '
}
fn main() {
let valid = true;
let result = match valid {
true => Box::new(Valid { value: 42 }) as Box<Encodable>,
false => Box::new(Error { error: "bork" }) as Box<Encodable>
};
let mut buf = String::new();
result.encode(&mut json::Encoder::new(&mut buf)).unwrap();
println!("{}", buf);
}
error: cannot convert to a trait object because trait `rustc-serialize::serialize::Encodable` is not object-safe [E0038]
答案 0 :(得分:2)
有两种方法可以在Rust中使用特征:
由于Encodable
不是对象安全的,我们无法使用动态调度,因为编译器不允许我们创建指向Encodable
的指针。
因此,我们必须使用静态调度。为此,我已将适用于Encodable
的代码移动到新的通用函数,并从每个臂调用它。
extern crate "rustc-serialize" as rustc_serialize;
use rustc_serialize::{json, Encodable};
#[derive(RustcEncodable)]
struct Valid {
value: u32
}
#[derive(RustcEncodable)]
struct Error {
error: &'static str // '
}
fn do_encode<E: Encodable>(e: E) -> () {
let mut buf = String::new();
e.encode(&mut json::Encoder::new(&mut buf)).unwrap();
println!("{}", buf);
}
fn main() {
let is_valid = true;
match is_valid {
true => do_encode(Valid { value: 42 }),
false => do_encode(Error { error: "bork" }),
};
}