如何使用特征默认方法访问BorrowMut超特征?

时间:2018-11-26 16:32:17

标签: rust

考虑以下Rust代码

trait Trait {
    fn show_name(&self) {}
}

struct Foo {
    name: String,
    things_and_stuff: usize,
}

impl Trait for Foo {
    fn show_name(&self) {
        println!("{}", self.name);
    }
}

struct Bar {
    name: String,
    other_field: i32,
}

impl Trait for Bar {
    fn show_name(&self) {
        println!("{}", self.name);
    }
}

两个show_name函数具有完全相同的代码。如果可以将该方法作为默认方法放在Trait上会很方便,但这是不可能的,因为特征无法访问结构字段。

我们可以在get_name(&self) -> &str上声明一个Trait方法,并在FooBar上实现它,但这不能解决重复代码的问题,因为两种实现都可以get_name中的相同。

最好避免代码重复。 Another question已经问过是否可以在特征中进行实地访问,而答案基本上是“否”。 但是,我在rust-internals论坛中发现a comment,暗示它已经已经。这是代码:

struct Fields {
    name: String,
}

trait Trait: BorrowMut<Fields> {
    // methods go here
}

impl<T> Trait for T where T: BorrowMut<Fields> {}

大概有一种方法可以使类型TBorrowMut<Fields>并使用它来允许Trait访问Fields的字段,但是到目前为止我还没有确定那将如何工作。

上面显示的代码片段应如何解决在特征中获取字段访问的问题?


我知道有人在讨论如何在语言(rust-internalsRFCanother RFC)的特征中添加字段访问,但是我想知道现在有什么可能。

1 个答案:

答案 0 :(得分:2)

  

答案基本上是“否”

答案实际上是(强调我的):

  

默认实现只能使用在特征或超级特征中定义的方法。

这就是您的代码段所做的:

trait Trait: BorrowMut<Fields>

要使其正常运行,请遵循您所引用的帖子中的建议:

  

所有选择实施BorrowMut<Foo>

的类型

因此,您需要为每种类型实现特征。我切换到Borrow是因为这里不需要可变性:

use std::borrow::Borrow;

struct Fields {
    name: String,
}

trait Trait: Borrow<Fields> {
    fn show_name(&self) {
        let fields: &Fields = self.borrow();
        println!("{}", fields.name);
    }
}

struct Foo {
    fields: Fields,
    things_and_stuff: usize,
}

impl Borrow<Fields> for Foo {
    fn borrow(&self) -> &Fields {
        &self.fields
    }
}

struct Bar {
    fields: Fields,
    other_field: i32,
}

impl Borrow<Fields> for Bar {
    fn borrow(&self) -> &Fields {
        &self.fields
    }
}

impl<T> Trait for T where T: Borrow<Fields> {}

我几乎可以肯定您不会喜欢此解决方案,因为它

  

因为两个实现都是相同的,所以无法解决重复代码的问题。

如果您的目标是减少代码中重复字符的数量,则可能更喜欢编写宏。

另请参阅: