我正在try 编写如下代码,其中我描述了特征中的一些代码接口,并提供了一个默认实现(本例中为模拟):

pub trait Person {
    fn say_hello(&self) -> String;
    
    fn stub() -> impl Person { // Doesn't work
        MockPerson {}
    }
}

pub struct MockPerson {}

impl Person for MockPerson {
    fn say_hello(&self) -> String {
        "hello".to_string()
    }
}

我正在try 找到正确的方式来表示特征Person有一个静态方法来返回一些有意未知的实现类型:

pub trait Person {
    ...
    // `impl Trait` only allowed in function and inherent method return types,
    // not in trait method return
    fn stub() -> impl Person { ... }
}

实现这一目标的最佳方式是什么?

推荐答案

即使允许此代码,它也不会是您想要的,因为:

  1. 您必须在call Person::stub()中提到一些任意的具体实现类型.特征的每个相关项都取决于实现类型.

  2. 这种类型将被允许实现stub()来做一些不同的事情.

解决方案是简单地编写一个不属于特征的函数.在Rust中,module包含特定概念的物品是完全正常的,而不是试图将所有东西都放入一种特征或类型的关联物品中.

mod person {
    pub trait Person {
        fn say_hello(&self) -> String;
    }

    pub fn stub() -> impl Person {
        MockPerson {}
    }
}

std:std::iter::empty()中的一个真实例子是std::iter模块中的一个函数,而不是std::iter::Iterator特征中的一个函数.

Rust相关问答推荐

泛型属性比较

如何在Rust中实现Functor trait?

从特征实现调用函数的Rust惯用方法

当rust中不存在文件或目录时,std::FS::File::Create().unwire()会抛出错误

为什么允许我们将可变引用转换为不可变引用?

使用Box优化可选的已知长度数组的内存分配

自定义结果枚举如何支持`?`/`FromResidual`?

我如何制作一个变异迭代器来锁定内部数据直到删除?

在Rust中判断编译时是否无法访问

如何返回 struct 体中向量的切片

通过mem::transmute将数组展平安全吗?

在1.5n次比较中找到整数向量中的最大和次大整数

有什么方法可以通过使用生命周期来减轻嵌套生成器中的当生成器产生时borrow 可能仍在使用错误?

有什么办法可以追踪泛型的单态化过程吗?

如何从 x86_64 Mac 构建 M1 Mac?

一个函数调用会产生双重borrow 错误,而另一个则不会

有没有办法阻止 rust-analyzer 使非活动代码变暗?

在 Rust 中获得准确时间的正确方法?

如何用另一个变量向量置换 rust simd 向量?

为移动和借位的所有组合实现 Add、Sub、Mul、Div