[英]How do I use a BorrowMut supertrait to access struct fields in a trait default method?
Consider the following Rust code 考虑以下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);
}
}
The two show_name
functions have exactly the same code. 这两个
show_name
函数具有完全相同的代码。 It would be convenient if I could put that method as a default method on Trait
, but that's not possible because traits cannot access struct fields. 如果可以将该方法作为
Trait
的默认方法,那将很方便,但这是不可能的,因为traits无法访问struct字段。
We could declare a get_name(&self) -> &str
method on Trait
and implement it on Foo
and Bar
, but that doesn't fix the problem of having duplicated code because both implementations of get_name
will be the same. 我们可以在
Trait
上声明一个get_name(&self) -> &str
方法,并在Foo
和Bar
上实现它,但这不能解决重复代码的问题,因为get_name
两种实现都是相同的。
It would be nice to avoid the code duplication. 最好避免代码重复。 Another question has already asked if field access is possible in traits, and the answer was basically "no".
另一个问题已经问到是否可以在性状中进行田间访问,而答案基本上是“否”。 However, I found a comment in the rust-internals forum suggesting that it's already possible.
但是,我在rust-internals论坛上发现了一条评论 ,暗示已经有可能。 Here's the code:
这是代码:
struct Fields {
name: String,
}
trait Trait: BorrowMut<Fields> {
// methods go here
}
impl<T> Trait for T where T: BorrowMut<Fields> {}
Presumably there's a way to make a type T
be BorrowMut<Fields>
and use that to allow Trait
to access Fields
's fields, but so far I'm not sure how that would work. 大概有一种方法可以使
T
类型成为BorrowMut<Fields>
并使用它来允许Trait
访问Fields
的字段,但是到目前为止,我不确定这将如何工作。
How is the code snippet shown above supposed to solve the problem of getting field access in traits? 上面显示的代码片段应如何解决在特征中获取字段访问的问题?
I know there are discussions of adding field access in traits to the language ( rust-internals , RFC , another RFC ), but I'd like to know what's possible now. 我知道有人在讨论将特质中的字段访问添加到该语言( rust-internals , RFC , 另一个RFC )中,但是我想知道现在有什么可能。
the answer was basically "no"
答案基本上是“否”
The answer actually says (emphasis mine): 答案实际上是(强调我的):
A default implementation can only use methods that are defined on the trait or in a super trait .
默认实现只能使用在特征或超级特征中定义的方法。
That's what your snippet does: 这就是您的代码段所做的:
trait Trait: BorrowMut<Fields>
To make it work, follow the advice from the post you are referencing: 要使其正常工作,请遵循您所引用的帖子中的建议:
all types which choose to implement
BorrowMut<Foo>
选择实现
BorrowMut<Foo>
所有类型
Thus, you need to implement the trait for each of your types. 因此,您需要为每种类型实现特征。 I switched to
Borrow
because you don't need mutability here: 我切换到
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> {}
I'm almost certain you won't like this solution because it 我几乎可以肯定您不会喜欢这种解决方案,因为它
doesn't fix the problem of having duplicated code because both implementations [...] will be the same
不能解决重复代码的问题,因为两个实现都相同
You may prefer to write a macro if your goal is to reduce the number of duplicate characters in your code. 如果您的目标是减少代码中重复字符的数量,则可能更喜欢编写宏。
See also: 也可以看看:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.