首页 > 解决方案 > 使用生命周期参数的约束 impl 中的 Rust 生命周期推断失败,但调整约束可以解决错误

问题描述

我正在使用一些代码,这些代码将一些责任委托给另一种类型,该类型持有对“数据”类型的引用。当我尝试实现委托为数据类型实现的特征时,我遇到了一个我不太理解的终身错误。

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)
    }
}

操场

这构建没有任何问题,但代码没有做任何不同的事情。据我所知,这两组约束在功能上应该是相同的,但显然第一个示例中生命周期参数的存在会以某种方式产生影响。当显式参数被删除时,编译器似乎推断出有效的生命周期,但我不知道我是否可以帮助它在第一个示例中做到这一点。

究竟是什么导致第一个示例失败,即使实际上相同的约束(但没有生命周期参数)工作正常?

有没有办法让第一个示例工作而不诉诸于复制' 和' impls 的约束ConvertsTestTestThunk

标签: rust

解决方案


推荐阅读