![](/img/trans.png)
[英]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.