从使用Box <trait> </trait>转换的结构中访问字段

时间:2015-04-11 22:17:01

标签: rust

我有以下代码,我认为这是非常明显的。我面临的问题是render函数:

fn render(&self) -> &'static str {
    self.view.value
}

编译器抱怨的地方:

attempted access of field `view` on type `&Self`, but no field with that name was found`

完整代码:

struct View1 {
    value: &'static str,
}

struct View2 {
    value: &'static str,
    another_value: &'static str,
}

struct Pattern<T> {
    view: T,
}

trait Renderable {
    fn render(&self) -> &'static str {
        self.view.value
    }
}

impl <T> Renderable for Pattern <T> {}

fn patterns() -> Vec<Box<Renderable>> {
    vec![
        Box::new(Pattern { view: View1 { value: "x" } }),
        Box::new(Pattern { view: View1 { value: "y" } }),
    ]
}

fn main() {
    let p = patterns();

    for x in p.iter() {
        println!("{}", x.render());
    }
}

1 个答案:

答案 0 :(得分:1)

是的,特征无法访问其实现者的字段。您需要提供访问方法。它们很小,应该进行优化:

trait View {
    fn value(&self) -> &'static str;
}

struct View1 {
    value: &'static str,
}

impl View for View1 {
    fn value(&self) -> &'static str { self.value }
}

struct View2 {
    value: &'static str,
    another_value: &'static str,
}

impl View for View2 {
    fn value(&self) -> &'static str { self.value }
}

trait Renderable {
    fn view(&self) -> &View;

    fn render(&self) -> &'static str {
        self.view().value()
    }
}

struct Pattern<T>
    where T: View
{
    view: T,
}

impl<T> Renderable for Pattern<T>
    where T: View
{
    fn view(&self) -> &View {
        &self.view
    }
}

fn patterns() -> Vec<Box<Renderable>> {
    vec![
        Box::new(Pattern { view: View1 { value: "x" } }),
        Box::new(Pattern { view: View2 { value: "y", another_value: "z" } }),
    ]
}

fn main() {
    let p = patterns();

    for x in p.iter() {
        println!("{}", x.render());
    }
}

基本上,traits是对象必须遵守的契约,这些契约的语言是函数名,参数类型和返回类型。如果特征需要能够获得viewvalue,那么这需要成为特征的一部分。

请注意, 的实现可以访问他们正在实现特征的结构的字段。由于实现专门针对一种类型,因此可以保证您可以访问相应的字段。