rust - 提供将 &self 转换为特征对象的方法

标签 rust traits

我有一个特征,我想在其中提供一个方法。该方法将根据一些助手来实现,这些助手在特征内部没有任何业务,并且非常重要,动态多态性比使它们通用更有意义。所以我的代码是

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/

相关文章:

rust - 为什么盒装变量需要显式类型才能传递给函数?

rust - 在Rust教程代码中获取 “error[E0599]: no method named write_fmt found”错误

io - 如何惯用/高效地将数据从 Read+Seek 传输到 Write?

rust - 哪个对堆分配点的引用是正确的?

macros - 我找不到 `mock!` 的定义

rust - 如何共享堆分配的特征对象?

python - 从类构造函数 [Python/Traits] 中更改属性参数

syntax - 在结构类型中包装 RefCell 和 Rc

rust - 如何使用try_trait解开具有不同错误类型的结果

rust - ** node.borrow()有什么作用?