[英]How do I bound a trait with a supertrait that uses the trait's associated type as a parameter?
[英]How do I use a BorrowMut supertrait to access struct fields in a trait default method?
考虑以下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
的默认方法,那将很方便,但这是不可能的,因为traits无法访问struct字段。
我们可以在Trait
上声明一个get_name(&self) -> &str
方法,并在Foo
和Bar
上实现它,但这不能解决重复代码的问题,因为get_name
两种实现都是相同的。
最好避免代码重复。 另一个问题已经问到是否可以在性状中进行田间访问,而答案基本上是“否”。 但是,我在rust-internals论坛上发现了一条评论 ,暗示已经有可能。 这是代码:
struct Fields {
name: String,
}
trait Trait: BorrowMut<Fields> {
// methods go here
}
impl<T> Trait for T where T: BorrowMut<Fields> {}
大概有一种方法可以使T
类型成为BorrowMut<Fields>
并使用它来允许Trait
访问Fields
的字段,但是到目前为止,我不确定这将如何工作。
上面显示的代码片段应如何解决在特征中获取字段访问的问题?
我知道有人在讨论将特质中的字段访问添加到该语言( rust-internals , RFC , 另一个RFC )中,但是我想知道现在有什么可能。
答案基本上是“否”
答案实际上是(强调我的):
默认实现只能使用在特征或超级特征中定义的方法。
这就是您的代码段所做的:
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> {}
我几乎可以肯定您不会喜欢这种解决方案,因为它
不能解决重复代码的问题,因为两个实现都相同
如果您的目标是减少代码中重复字符的数量,则可能更喜欢编写宏。
也可以看看:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.