在盒装 Fn 性状泛型上实现特征会导致生存期问题

Implementing traits on boxed Fn trait generics leads to lifetime issues

提问人:Sam Kinney 提问时间:10/3/2023 最后编辑:Sam Kinney 更新时间:10/3/2023 访问量:52

问:

这里有点像 Rust 的初学者。我正在尝试为映射数据类型的函数实现一个特征,这些函数将类型实现映射到自身。 看起来像这样:RingRingRing

trait Ring {
    fn plus(&self, other: &Self) -> Self;
    fn times(&self, other: &Self) -> Self;
    fn negate(&self) -> Self;
}

我尝试的实现如下所示:

impl <R: Ring> Ring for Box<dyn Fn(&R) -> R> {

    //(f+g)(a) = f(a) + g(a)
    fn plus(&self, other: &Self) -> Self {
        Box::new(move |x: &R| -> R {self(x).plus(&other(x))})
    }
    //(fg)(a) = f(g(a))
    fn times(&self, other: &Self) -> Self {
        Box::new(move |x: &R| -> R {self(&other(x))})
    }
    //(-f)(a) = -(f(a))
    fn negate(&self) -> Self {
        Box::new(move |a: &R| -> R {self(a).negate()})
    }
}

请注意,我用 代替了语法上更好的,因为编译器禁止在这里使用。Box<dyn Fn(&R) -> Rimpl Fn(&R) -> Rimpl Trait

提供的错误消息是:

error: lifetime may not live long enough
  --> src/main.rs:73:9
   |
72 |     fn plus(&self, other: &Self) -> Self {
   |             - let's call the lifetime of this reference `'1`
73 |         Box::new(move |x: &R| -> R {self(x).plus(&other(x))})
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'1` must outlive `'static`

我尝试过一些回应:

i) 向方法添加通用生存期注释。这使得特征不再将它们识别为实现它需要的方法。尝试编辑自身以包含这些注释会产生一条错误消息,告诉我我的终身名称隐藏了预先存在的名称。RingRing

ii) 用 boxing 代替 ,并注释为静态。这会产生生存期不匹配。dyn Fn(&R) -> R + 'staticdyn Fn(&R) -> Rself

iii) 验证加号、乘以法和否定是否按预期工作,在实现块之外重述时没有编译器错误——它们确实如此。

我怎样才能确保它的寿命确实是我需要的?&self

泛型 闭包 特征对象

评论

0赞 Chayim Friedman 10/3/2023
恐怕除非你能改变,否则你无法实现这个特征。Ring
0赞 Sam Kinney 10/3/2023
@ChayimFriedman 这可能适用于我的项目,具体取决于更改的样子:您能否更详细地介绍一下需要更改的内容?
0赞 Chayim Friedman 10/4/2023
一种可能的选择是采取代替 .selfself

答: 暂无答案