Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/rust/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Rust 从函数返回的闭包与就地定义不一致_Rust_Closures_Actix Web - Fatal编程技术网

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

在尝试使用实现一个简单的web服务器应用程序时,我遇到了明显不一致的Rust闭包行为,这些行为不知道如何解释

我有以下代码:

使用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)
}

先生,你是我的英雄!