Я работаю с некоторым кодом, который делегирует некоторую ответственность другому типу, который содержит ссылку на тип «data». Когда я пытаюсь реализовать черту, которую делегат реализует для типа данных, я сталкиваюсь с пожизненной ошибкой, которую я не совсем понимаю.
trait Converts<T> {
fn convert(&mut self, from: T);
}
trait CompoundConversion<C> {
fn convert(&self, to: &mut C);
}
struct TestThunk<'a> {
test: &'a Test,
}
impl<'a, C> CompoundConversion<C> for TestThunk<'a>
where C: Converts<String> + Converts<isize>
{
fn convert(&self, to: &mut C) {
to.convert(self.test.name.to_owned());
to.convert(self.test.id);
}
}
struct Test {
name: String,
id: isize,
}
impl Test {
fn thunk<'a>(&'a self) -> TestThunk<'a> {
TestThunk {
test: self
}
}
}
// Produces an error:
impl<'a, C> CompoundConversion<C> for Test
where TestThunk<'a>: CompoundConversion<C>
{
fn convert(&self, to: &mut C) {
self.thunk().convert(to)
}
}
Я думаю, что это не работает, потому что 'a
выводится быть действительным в течение времени жизни значения Test
, а не просто вызова метода.
Что меня действительно смущает, так это то, что изменение ограничений немного исправляет это.
// Works:
impl<C> CompoundConversion<C> for Test
where C: Converts<String> + Converts<isize>
{
fn convert(&self, to: &mut C) {
self.thunk().convert(to)
}
}
Playground
Это построение без каких-либо проблемы, но код не делает ничего другого. Насколько я могу судить, эти два набора ограничений должны быть функционально идентичными, но очевидно, что наличие параметра времени жизни в первом примере имеет какое-то значение. Когда явный параметр удален, компилятор, по-видимому, выводит срок службы, который работает, но я понятия не имею, смогу ли я помочь ему сделать это и для первого примера.
Что именно приводит к сбою первого примера, несмотря на то, что ограничение, которое фактически одинаково (но без параметра времени жизни), работает нормально?
Есть ли способ заставить первый пример работать, не прибегая к дублированию ограничений Converts
на обоих Test
' s и TestThunk
это означает?