问题:我在一个方法中收到了一个错误信息 "XXXXXXX 在还未归还的情况下被放弃",其中 XXXXXXX 有效期到方法的末尾(这是可以接受的),但 Rust 不必要地期望它能够与输入引用一样长寿,因为这些引用具有显式生命周期。
以下是一些设置信息:我有一个结构体,它可以迭代文本内容中找到的所有查询。
我想要做的是找到一种方法,向Rust证明只要它认为不需要
以下是一些设置信息:我有一个结构体,它可以迭代文本内容中找到的所有查询。
pub struct QueryRangeItr<'a> {
inverted: bool,
query: &'a str,
content: &'a str,
}
它需要查询和内容的引用,并期望该实例与查询/内容一样长。目前为止,一切都很好。
impl<'a> QueryRangeItr<'a> {
fn new(query: &'a str, content: &'a str, inverted: bool) -> QueryRangeItr<'a> {
Self {
inverted,
query,
content,
}
}
}
我有一个静态方法,允许您对每个找到的查询执行转换。它接受一个闭包并将其应用于查询,然后给您一个新的String
,该字符串没有生命周期依赖关系。由于返回值没有生命周期,我实际上不想在这里为查询和内容引入生命周期,但如果我不这样做,Rust会告诉我需要...因此,它们具有生命周期要求。单独使用时,这很好。
问题出现在另一个静态方法上,它调用了两次transform
来转换查询和非查询内容。首先,它调用transfrom
来应用一个闭包到找到的查询。结果反馈到另一个transform
方法的调用中,但这次是对其余内容应用变换。
impl<'a> QueryRangeItr<'a> {
pub fn transform<T>(
query: &'a str,
content: &'a str,
transform: T,
inverted: bool,
) -> String where T: Fn(&str) -> String {
let selects = Self::new(query, content, true);
// ...
// returns a `String` with no lifetime dependency on input params
}
pub fn transform_all<TQ, TNQ>(
query: &'a str,
content: &'a str,
transform_query: TQ,
transform_non_query: TNQ,
) -> String
where
TQ: Fn(&str) -> String,
TNQ: Fn(&str) -> String,
{
let transformed_content = Self::transform(query, content, &transform_query, false);
let transformed_query = transform_query(query);
let transformed = Self::transform(&transformed_query, &transformed_content, transform_non_query, true); // <--- Rust expects `transformed_content` and `transformed_query` to match the lifetime of `query` and `content`
transformed
}
}
transformed_content
和transformed_query
在transform_all
结束时会被销毁...这是有意义的,但是Rust希望它们的生命周期与输入参数query
和content
('a)一样长,而它们却无法做到。
实际上我并不需要让它们存在更长的时间。一旦我得到了transformed
,我就不再需要它们了。然而,在query
和content
上设置生命周期让Rust认为它们需要比实际需要的时间更长,导致出现了这个错误:
115 | impl<'a> QueryRangeItr<'a> {
| -- lifetime `'a` defined here
...
200 | let transformed = Self::transform(&transformed_query, &transformed_content, transform_non_query, true);
| ------------------------------------^^^^^^^^^^^^^^^^^^^^----------------------------
| | |
| | borrowed value does not live long enough
| argument requires that `transformed_content` is borrowed for `'a`
201 | transformed
202 | }
| - `transformed_content` dropped here while still borrowed
如果我移除生命周期,将会出现以下错误:
error[E0621]: explicit lifetime required in the type of `query`
--> src/range/query_range_iterator.rs:130:23
|
125 | query: &str,
| ---- help: add explicit lifetime `'a` to the type of `query`: `&'a str`
...
130 | let selects = Self::new(query, content, invert);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetime `'a` required
如果我尝试为我的转换方法定义一个不同的生命周期 'a
('b
或 '_
),我会得到这样的结果:
error[E0521]: borrowed data escapes outside of associated function
--> src/range/query_range_iterator.rs:130:23
|
126 | content: &'_ str,
| ------- `content` is a reference that is only valid in the associated function body
...
130 | let selects = Self::new(query, content, invert);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `content` escapes the associated function body here
我想要做的是找到一种方法,向Rust证明只要它认为不需要
transformed_content
和transformed_query
,我就不需要它们。你有什么想法吗?
error[E0716]
error E0716: temporary value dropped while borrowed (rust),并且它链接回了这个问题。 - JamesThomasMoon