Как вывести значение из объектно-безопасного объекта черты?
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`
Есть ли способ заставить этот шаблон произойти?
Есть ли что-то фундаментальное, чего я, кажется, упускаю?
В случае, если это невозможно достичь, каков хороший способ обойти это?
1 ответ
Как намекнул компилятор, черта не может быть определена статически, потому что вы имеете дело с динамической диспетчеризацией. В этом сценарии по-прежнему возможно владение 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() {}