我有一个特征,我想在其中提供一个方法。该方法将根据一些助手来实现,这些助手在特征内部没有任何业务,并且非常重要,动态多态性比使它们通用更有意义。所以我的代码是
fn use_trait(x: &Trait) {
println!("object says {}", x.needed());
}
trait Trait {
fn needed(&self) -> &str;
fn provided(&self) {
use_trait(self);
}
}
struct Struct();
impl Trait for Struct {
fn needed(&self) -> &str {
"Hello, world!"
}
}
fn main() {
Struct().provided();
}
但是,does not compile ,有错误:
error[E0277]: the trait bound `Self: std::marker::Sized` is not satisfied
--> <anon>:9:19
|
9 | use_trait(self);
| ^^^^ the trait `std::marker::Sized` is not implemented for `Self`
|
= help: consider adding a `where Self: std::marker::Sized` bound
= note: required for the cast to the object type `Trait`
我明白为什么 - 不能保证有人不会为未确定大小的类型实现特征(从 &T where T: Trait
转换为 &Trait
需要 T: Sized
,但声明不需要那个)。
但是,建议不会满足我的需要。我可以添加
fn needed(&self) -> &str where Self: Sized
然后是 needed()
在 &Trait
上不会 可以访问方法(因为 Trait : ?Sized
),这使得事情变得无用,因为类型(实际做一些有用的事情)总是被处理为 Arc<Trait>
.并添加
trait Trait: Sized
更糟,因为这不允许 &Trait
完全没有(Trait
作为一个类型没有大小,所以 Trait
类型不实现特征 Trait
)。
我当然可以简单地制作
fn use_trait<T: Trait>(x: &T)
但是在实际代码中它背后有很多东西,所以我不希望在那里进行单态化,特别是因为 trait 否则总是作为 trait 对象处理。
有没有办法告诉 Rust impl Trait
的所有类型必须调整大小,这里是一个应该适用于所有这些方法的定义?
最佳答案
您需要在 Trait
及其实现上添加一个额外的 as_trait
函数:
trait Trait {
fn needed(&self) -> &str;
fn provided(&self) {
use_trait(self.as_trait());
}
fn as_trait(&self) -> &Trait;
}
struct Struct();
impl Trait for Struct {
fn needed(&self) -> &str {
"Hello, world!"
}
fn as_trait(&self) -> &Trait {
self as &Trait
}
}
你可以在 Playground 上试试。 ( trait objects )
关于rust - 提供将 &self 转换为特征对象的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42121299/