Rust 将变量移出其环境的扭曲过滤器
我正在尝试实现一个过滤器,它位于我的所有路由中,提取一个头并将一个可能的令牌与存储在我的系统上的令牌相匹配 我想实现类似的东西,但我得到了错误 应为实现Fn特性的闭包,但此闭包 仅实现FnOnce闭包是FnOnce,因为它移动 将变量tmp移出其环境 我有点明白编译器的意思,但不知道如何解决它。 我想让tmp=store.clone这样做会更好 我有过滤器:Rust 将变量移出其环境的扭曲过滤器,rust,rust-warp,Rust,Rust Warp,我正在尝试实现一个过滤器,它位于我的所有路由中,提取一个头并将一个可能的令牌与存储在我的系统上的令牌相匹配 我想实现类似的东西,但我得到了错误 应为实现Fn特性的闭包,但此闭包 仅实现FnOnce闭包是FnOnce,因为它移动 将变量tmp移出其环境 我有点明白编译器的意思,但不知道如何解决它。 我想让tmp=store.clone这样做会更好 我有过滤器: pub fn haystack_auth_header(store: Store) -> impl Filter<Extrac
pub fn haystack_auth_header(store: Store) -> impl Filter<Extract = (Store,), Error = Rejection> + Clone {
let tmp = store.clone();
warp::header("Authorization").and_then (|auth_header: String| async move {
// Authorization: BEARER authToken=xxxyyyzzz
let result = auth_token(&auth_header); //-> IResult<&'a str, (&'a str, &'a str), (&'a str, ErrorKind)> {
if result.is_err() {
return Err(reject::custom(HayStackAuthToken));
}
let (_, key_value) = result.unwrap();
let auth_token_result = tmp.read().get_authtoken();
if auth_token_result.is_err() {
return Err(reject::custom(HayStackAuthToken));
}
let auth_token_option = auth_token_result.unwrap();
if auth_token_option.is_none() {
return Err(reject::custom(HayStackAuthToken));
}
let auth_token = auth_token_option.unwrap();
if auth_token != key_value.1 {
return Err(reject::custom(HayStackAuthToken));
}
Ok(tmp)
})
}
为什么克隆在这里不起作用
完全错误是
error[E0525]: expected a closure that implements the `Fn` trait, but this closure only implements `FnOnce`
--> src/server/mod.rs:997:45
|
997 | warp::header("Authorization").and_then (|auth_header: String| async move {
| ___________________________________--------__^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^_-
| | | |
| | | this closure implements `FnOnce`, not `Fn`
| | the requirement to implement `Fn` derives from here
998 | |
999 | | // Authorization: BEARER authToken=xxxyyyzzz
1000 | | let result = auth_token(&auth_header); //-> IResult<&'a str, (&'a str, &'a str), (&'a str, ErrorKind)> {
... |
1026 | | Ok(tmp.clone())
1027 | | })
| |_____- closure is `FnOnce` because it moves the variable `tmp` out of its environment
这个问题表明,您对fn层级还没有明确的区分: 摘自 Warp的过滤功能需要实现这个特性。 这意味着您无法访问外部contextread:环境 第一次调用闭包,然后调用闭包,该函数将使用唯一可用的tmp变量,因此它在以后的调用中不可用。由于闭包是对上下文的所有权,这意味着它只实现了一次
正如@msrd0在评论中所建议的,这可能可以通过在函数中移动该调用来解决,但我需要一个MRE来确定这一点。在创建了一个简单的测试用例后,我成功地使用了以下函数
pub fn haystack_auth_header(store: Store) -> impl Filter<Extract = (Store,), Error = Rejection> + Clone {
warp::header("Authorization").and_then (
move |auth_header: String|
{
let tmp = store.clone();
async move {
let tmp = tmp.clone();
if tmp.read().get_authtoken().is_none() {
return Err(reject::custom(HayStackAuthToken));
}
Ok(tmp.clone())
}
}
)
}
因此,最后只需要在正确的位置进行克隆。请回答您的问题,并粘贴您得到的准确完整的错误-这将帮助我们了解问题所在,以便我们能够提供最好的帮助。有时,试图解释错误消息是很棘手的,而这实际上是错误消息的另一个重要部分。请使用直接运行编译器的消息,而不是IDE生成的消息,IDE可能会试图为您解释错误。很难回答您的问题,因为它不包含错误。我们无法说出代码中存在哪些板条箱及其版本、类型、特征、字段等。如果您试图重现您的错误(如果可能的话),或者在全新的货运项目中,那么我们将更容易帮助您,然后您的问题将包括附加信息。您可以使用以下方法减少在此处发布的原始代码。谢谢商店是。。。UserAuthStore是-请不要仅使用散文描述代码。相反,请提供一个包含再现错误所需的所有定义,但不包括其他内容的示例。例如,您的筛选器的大部分逻辑可能可以替换为像true这样的硬编码值。我假设问题是您将tmp=store.clone放在了闭包的外部而不是内部,但如果没有示例,很难说我可以编译自己。我看到您正在编辑以添加更多信息,但您似乎忽略了生成最小示例的请求。请不要忽视这一点。
pub fn haystack_auth_header(store: Store) -> impl Filter<Extract = (Store,), Error = Rejection> + Clone {
warp::header("Authorization").and_then (
move |auth_header: String|
{
let tmp = store.clone();
async move {
let tmp = tmp.clone();
if tmp.read().get_authtoken().is_none() {
return Err(reject::custom(HayStackAuthToken));
}
Ok(tmp.clone())
}
}
)
}