我如何传达一个带有引用的泛型类型只需要通过函数调用生存?

How do I communicate that a generic type with a reference in it only needs to live through a function call?

我有两个结构,其中一个的类型参数设置为对另一个结构的引用。当我将该引用作为函数中的参数时,我不知道如何发出生命周期不应依赖的信号。

我已将其缩减为这个示例:

use std::marker::PhantomData;

struct Foo<T> {
    bar_type: PhantomData<T>,
}

struct Bar {}

impl<T> Foo<T> {
    fn takebar(&mut self, bar: T) {}
}

fn main() {
    let mut foo: Foo<&Bar> = Foo {
        bar_type: PhantomData,
    };
    let bar = Bar {};

    foo.takebar(&bar);
}

这给了我以下编译器错误:

error[E0597]: `bar` does not live long enough
  --> src/main.rs:19:18
   |
19 |     foo.takebar(&bar);
   |                  ^^^ borrowed value does not live long enough
20 | }
   | - `bar` dropped here while still borrowed
   |
   = note: values in a scope are dropped in the opposite order they are created

我知道 foo 需要和 bar 一样长,所以我可以 "resolve" 通过在 foo 之前声明 bar 来反转他们的销毁令。

这对我的情况不起作用,更重要的是,我不确定为什么会发生这种情况或如何避免这种情况。我已经尝试了各种明确的生命周期设置,其中 none 似乎可以解决问题。如果我把 takebar(&mut self, ... 变成 takebar(&self, ...,它也可以,但我不能总是那样做。如果我将类型参数从结构移动到函数,它也可以工作,但同样,不能总是这样做。

如何传达 &bar 引用不应绑定到 foo 的生命周期中,而实际上只需要通过函数调用存在?

你不能。

更简单的复制:

struct Foo<T>(Option<T>);
struct Bar;

impl<T> Foo<T> {
    fn takebar(&mut self, bar: T) {}
}

fn main() {
    let mut foo: Foo<&Bar> = Foo(None);
    let bar = Bar;

    foo.takebar(&bar);
}

编译器只关心函数签名。 可能 takebar 的实现与现有的函数签名是存储它的一个:

fn takebar(&mut self, bar: T) {
    self.0 = Some(bar)
}

因此,示例代码必须被阻止编译。

通常情况下,我会提倡在函数上放置另一个类型参数并表达您需要执行的操作,但您已经排除了这种可能性:

fn takebar<T2>(&mut self, bar: T2)
where
    T2: PartialEq<T>,
{
    self.0.take();
}

If I turn takebar(&mut self, ... into takebar(&self, ..., it also works

是的,因为那时您不能存储该值(除非您添加内部可变性,在这种情况下错误会再次出现)。

另请参阅: