如何将值移出对象安全特征对象?



Mech带有一个驱动程序,这是一个Named实体。在运行时,省略的Mech构造函数会查阅外部源以获取要使用的特定类型的驱动程序。

trait Named {
fn name(self) -> String;
}
struct Person {
first_name: String,
last_name: String
}
impl Named for Person {
fn name(self) -> String {
format!("{} {}", self.first_name, self.last_name)
}
}
pub struct Mech<'a> {
driver: Box<Named + 'a>,
}
impl<'a> Mech<'a> {
pub fn driver_name(self) -> String {
self.driver.name()
}
}

方法driver_name将所有权返回给String,以便进一步用于链式调用(在实际代码中它是一个Command(。编译失败,出现:

error[E0161]: cannot move a value of type Named + 'a: the size of Named + 'a cannot be statically determined
--> src/lib.rs:22:9
|
22 |         self.driver.name()
|         ^^^^^^^^^^^

使性状Sized无法实现对象安全:

trait Named: Sized {
fn name(self) -> String;
}

error[E0038]: the trait `Named` cannot be made into an object
--> src/lib.rs:17:5
|
17 |     driver: Box<Named + 'a>,
|     ^^^^^^^^^^^^^^^^^^^^^^^ the trait `Named` cannot be made into an object
|
= note: the trait cannot require that `Self : Sized`

有没有办法使这种模式发生?

我似乎缺少什么基本的东西吗?

如果这无法实现,有什么好方法可以解决它?

正如编译器所暗示的,特征不能静态确定,因为你正在处理动态调度。在这种情况下,仍然可以使用self: Box<Self>进行所有权。

trait Named {
fn name(self: Box<Self>) -> String;
}
struct Person {
first_name: String,
last_name: String,
}
impl Named for Person {
fn name(self: Box<Self>) -> String {
format!("{} {}", self.first_name, self.last_name)
}
}
pub struct Mech<'a> {
driver: Box<Named + 'a>,
}
impl<'a> Mech<'a> {
pub fn driver_name(self) -> String {
self.driver.name()
}
}
fn main() {}

最新更新