Rust 有没有办法延长局部定义变量的生存期?
用例:我有一个分页的GraphQLAPI,其中许多不同的实体返回一个不透明光标和一个布尔值Rust 有没有办法延长局部定义变量的生存期?,rust,Rust,用例:我有一个分页的GraphQLAPI,其中许多不同的实体返回一个不透明光标和一个布尔值hasNext。我希望将这些实体作为TryStream提供,以允许在获取所有页面时进行计算 我定义了一个特征来抽象它获取数据获取单个页面: trait PaginatedEntityQuery { type ResponseData; fn get_cursor(data: &Self::ResponseData) -> Option<String>; fn
hasNext
。我希望将这些实体作为TryStream
提供,以允许在获取所有页面时进行计算
我定义了一个特征来抽象它<代码>获取数据获取单个页面:
trait PaginatedEntityQuery {
type ResponseData;
fn get_cursor(data: &Self::ResponseData) -> Option<String>;
fn has_next_page(data: &Self::ResponseData) -> bool;
fn get_data<'a>(
&self, // access to query variables
backend: &'a Backend, // access to a backend to get data from
cursor: Option<String>, // the cursor in the pagination
) -> Pin<Box<dyn Future<Output = Result<Self::ResponseData>> + 'a>>;
}
现在我想定义一下
struct SomeEntityQuery { filter: String }
impl PaginatedEntityQuery for SomeEntityQuery { /* … */ }
最后,我可以定义一个函数,它使用get_paginated_entities
来完成繁重的工作:
fn get_some_entities(filter: String, /* … */) -> impl TryStream<Ok = Vec<SomeOtherType>, Error = anyhow::Error> + 'a {
backend.get_paginated_entities(&SomeEntityQuery { filter }).map_ok /* … */
}
fn获取一些实体(过滤器:字符串,/*…*/)->impl TryStream+'a{
backend.get_paginated_entities(&SomeEntityQuery{filter}).map_ok/**/
}
当然,这是行不通的。我在get\u some\u entities
中定义了SomeEntityQuery
的一个实例,但我返回的是所拥有的值。Rust无法知道,SomeEntityQuery
的任何部分实际上都没有显示在返回值中
我会在中进行查询:&'a T
获取一些实体,而不是ref,但是我会在异步移动中移出T
,我给尝试展开,因为它是FnMut
,所以闭包不能多次拥有它。它有查询
必须共享。此外,删除ref formT
会使crust抱怨类型参数可能活得不够长
有没有办法确保查询本身的值不需要与查询返回的值一样长?或者可能延长查询的生存期?如果需要,我可以大量复制查询。它是轻量级的,性能受网络限制。首先让我们做一个简单的工作示例,我们可以实际编译:
trait查询{
fn获取_数据结果{
数据:&'data str,
}
结构后端{
数据库_数据:字符串,
}
结构SomeQuery{
长度过滤器:使用,
}
对SomeQuery的impl查询{
fn获取_数据结果{
查询。获取_数据(自)
}
}
fn获取某些实体的结果{
查询。获取_数据(自)
}
这很好,因为get\u data
还指定query
的生存期未链接到结果
fn get_data Result让我们首先做一个简单的工作示例,我们可以实际编译:
trait查询{
fn获取_数据结果{
数据:&'data str,
}
结构后端{
数据库_数据:字符串,
}
结构SomeQuery{
长度过滤器:使用,
}
对SomeQuery的impl查询{
fn获取_数据结果{
查询。获取_数据(自)
}
}
fn获取某些实体的结果{
查询。获取_数据(自)
}
这很好,因为get\u data
还指定query
的生存期未链接到结果
fn get_data result非常感谢你接受了我问得不好的问题,并且回答得这么好!这无疑帮助我拓展了关于生命周期的视野。我会接受答案,因为回答这个问题,它能很好地回答问题。不幸的是,我的程序中的类型似乎有点复杂。我我想我的问题源于这样一个事实,get_data
不会返回Result>
。因此,在我看来,Pin
属于get_data
的self
life?这给了我:life不匹配,就像查询一样。get_data
在paginated_entities
中,实体在query
的生存期内返回一些内容,而不仅仅是在后端的生存期内。但是,谢谢,我会尝试看看是否可以解决这个问题。@AleksandarDimitrov异步
的生存期确实更为复杂,不幸的是,我对未来的还不太熟悉,无法给出详细的解释明确的答案,特别是没有一个最小的可重复的例子。然而,我认为问题在于未来
总是受到它使用的引用的限制。假设获取数据
返回一个使用&self
的未来,即使&self
不在响应数据中,因为未来
是懒惰的de>&self
的寿命不够长。请看,您是否可以尝试将&self
更改为self:Rc
(当然可以相应地重构其余代码)?使用Rc
删除了self
上的生存期限制。如果这样做有效,我将编辑我的答案。非常感谢你接受了我问得不好的问题,并很好地回答了它!这肯定有助于扩展我关于生存期的视野。我会接受答案,因为回答这个问题,它能很好地回答问题。不幸的是,我的程序中的类型似乎有点复杂。如果有必要,我将尝试应用您的建议并问另一个问题!我认为我的问题源于get\u data
不返回Result>
。因此,在我看来,Pin
归get\u data
的所有elf
lifetime?这给了我:lifetime失配,如query。get_data
inpaginated_entities
在query
的生命周期内返回一些内容,而不仅仅是在后端的生命周期内。但是,谢谢,我会尝试看看是否可以纠正这种情况。@AleksandarDimitrovasync
生命周期确实更为复杂非常复杂,不幸的是,我对Future
不够熟悉,无法给出一个明确的答案,特别是没有一个最小的可复制的例子。然而,我认为问题是Future
总是受到它所使用的引用的限制。假设get\u data
返回一个使用&self
的未来,即使&self
不在ResponseData
中,因为Future
s是懒惰的&self
活得不够长。你能看一下吗
fn get_some_entities(filter: String, /* … */) -> impl TryStream<Ok = Vec<SomeOtherType>, Error = anyhow::Error> + 'a {
backend.get_paginated_entities(&SomeEntityQuery { filter }).map_ok /* … */
}