我如何传达一个带有引用的泛型类型只需要通过函数调用生存?
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
是的,因为那时您不能存储该值(除非您添加内部可变性,在这种情况下错误会再次出现)。
另请参阅:
我有两个结构,其中一个的类型参数设置为对另一个结构的引用。当我将该引用作为函数中的参数时,我不知道如何发出生命周期不应依赖的信号。
我已将其缩减为这个示例:
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, ...
intotakebar(&self, ...
, it also works
是的,因为那时您不能存储该值(除非您添加内部可变性,在这种情况下错误会再次出现)。
另请参阅: