如何从对象安全特征对象中移出一个值?
How to move a value out of an object-safe trait object?
一个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
returns 对 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() {}
一个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
returns 对 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() {}