Rust 从函数返回的闭包与就地定义不一致
在尝试使用实现一个简单的web服务器应用程序时,我遇到了明显不一致的Rust闭包行为,这些行为不知道如何解释 我有以下代码:Rust 从函数返回的闭包与就地定义不一致,rust,closures,actix-web,Rust,Closures,Actix Web,在尝试使用实现一个简单的web服务器应用程序时,我遇到了明显不一致的Rust闭包行为,这些行为不知道如何解释 我有以下代码: 使用actix_web::{web,App,HttpServer}; #[衍生(克隆)] 结构配置{ val1:字符串, val2:字符串, val3:字符串, } fn main(){ 让conf=Config{ val1:“just.”to_string(), val2:“some.”to_string(), val3:“数据”。到_字符串(), }; HttpSer
使用actix_web::{web,App,HttpServer};
#[衍生(克隆)]
结构配置{
val1:字符串,
val2:字符串,
val3:字符串,
}
fn main(){
让conf=Config{
val1:“just.”to_string(),
val2:“some.”to_string(),
val3:“数据”。到_字符串(),
};
HttpServer::新建(移动)||
App::new().configure(创建配置(&conf))
)
.bind(“127.0.0.1:8088”)
.unwrap()
.run()
.unwrap();
}
fn create_config impl FnOnce(&mut web::ServiceConfig)+'a{
移动|应用程序:&mut web::ServiceConfig |{
//必须克隆配置,因为web::get().to根据定义需要
//它的参数具有静态生存期,该生存期长于'a'
让我的_拥有_conf_clone=conf.clone();
应用程序服务(
web::范围(“/user”)
.route(“,web::get().to(move | | get_user(&my_own_conf_clone)))
);
}
}
fn get_user(conf:&Config)->String{
println!(“Config{}is{}here!”,conf.val3,conf.val1);
“User McUser”。to_string()
}
这个代码有效。注意我传递给web::get().to
的闭包。我使用它将Config
对象向下传递给get\u user
,并根据需要使用一个没有参数的函数将web::get().to
。此时,我决定将闭包生成转移到一个单独的函数:
fn创建\u config impl FnOnce(&mut web::ServiceConfig)+'a{
移动|应用程序:&mut web::ServiceConfig |{
应用程序服务(
web::范围(“/user”)
.route(“,web::get().to(gen\u get\u user(conf)))
);
}
}
fn gen\u get\u user(conf:&Config)->impl fn()->String{
让我的_拥有_conf_clone=conf.clone();
移动| |获取|用户(&我自己的|配置|克隆)
}
fn get_user(conf:&Config)->String{
println!(“Config{}is{}here!”,conf.val3,conf.val1);
“User McUser”。to_string()
}
此代码无法编译,出现以下错误:
error[E0277]: the trait bound `impl std::ops::Fn<()>: actix_web::handler::Factory<_, _>` is not satisfied
--> src/main.rs:30:39
|
30 | .route("", web::get().to(gen_get_user(conf)))
| ^^ the trait `actix_web::handler::Factory<_, _>` is not implemented for `impl std::ops::Fn<()>`
error[E0277]:不满足特性绑定'impl std::ops::Fn:actix_web::handler::Factory'
-->src/main.rs:30:39
|
30 |.route(“”,web::get().to(gen_get_user(conf)))
|^^未为'impl std::ops::Fn'实现特性'actix_web::handler::Factory'`
为什么它在第二种情况下失败,但在第一种情况下却没有失败?为什么在第一种情况下,特性工厂满足,但在第二种情况下却不满足?可能是工厂(其来源)的错?在这种情况下,是否有一种不同的方式返回关闭?你能建议其他的方法吗?(注意,工厂
不是公共的,所以我不能自己直接实现)
如果你想玩弄代码,我这里有:
请注意,您可以在提交之间移动,以查看处于工作或失败状态的代码。然后使用impl Trait
作为返回类型,除该值实现的Trait
之外的所有其他类型信息都将被删除
在这种特殊情况下,闭包move | | get_user(&my_own_conf_clone)
实现Fn()->String
和clone
,但在返回clone
后将被擦除
但是由于为Fn()->String+Clone
实现了Factory
,而不是为Fn()->String
实现了返回值,因此返回值不再实现Factory
这可以通过将gen\u get\u user
更改为
fn gen_get_user(conf: &Config) -> impl Fn() -> String + Clone{
let my_own_conf_clone = conf.clone();
move || get_user(&my_own_conf_clone)
}
先生,你是我的英雄!