Rust 特征'std::ops::Fn<;()>;`不是为[closure…]实现的,而是仅使用外部范围的绑定实现的 fn main(){ 设s=Some(“xyz”.to_string());//编译器错误 让foo=Box::new(| | s)作为Box选项>;//确定 让bar=Box::新建(| | Some(“xyz”).to_string())作为Box选项>; println!(“{:?}”,foo()); println!(“{:?}”,bar()); }

Rust 特征'std::ops::Fn<;()>;`不是为[closure…]实现的,而是仅使用外部范围的绑定实现的 fn main(){ 设s=Some(“xyz”.to_string());//编译器错误 让foo=Box::new(| | s)作为Box选项>;//确定 让bar=Box::新建(| | Some(“xyz”).to_string())作为Box选项>; println!(“{:?}”,foo()); println!(“{:?}”,bar()); },rust,Rust,给出了错误 fn main() { let s = Some("xyz".to_string()); //compiler error let foo = Box::new(|| s) as Box<Fn() -> Option<String>>; //ok let bar = Box::new(|| Some("xyz".to_string())) as Box<Fn() -> Option<String>

给出了错误

fn main() {

    let s = Some("xyz".to_string());  //compiler error

    let foo = Box::new(|| s) as Box<Fn() -> Option<String>>;  //ok

    let bar = Box::new(|| Some("xyz".to_string())) as Box<Fn() -> Option<String>>;

    println!("{:?}", foo());
    println!("{:?}", bar());
}
error[E0277]:特征绑定`[closure@src/main.rs:5:24:5:28 s:std::option::option]:std::ops::Fn`不满足
-->src/main.rs:5:15
|
5 |让foo=Box::新(| | s)作为Box选项>;
|^^^^^^^^^^^^^^^^^^^^^^^未为实现特性“std::ops::Fn”`[closure@src/main.rs:5:24:5:28 s:std::option::option]`
|
=注意:强制转换到对象类型`std::ops::Fn()->std::option::option()时需要`
错误:由于上一个错误而中止
州政府的文件:

Fn由闭包自动实现,闭包只对捕获的变量进行不可变的引用,或者根本不捕获任何内容

s
是不可变的,但它不是引用,我正在移动它

如果我调用
s.clone()
,编译器错误就会消失,但在我的实际情况中,我希望避免这种情况

如果我使用
FnMut
FnOnce
抱怨不知道大小,即使它已装箱,也会出现相同的错误

有没有一种方法可以让移动的数据起作用


如果允许,第二次调用闭包时会发生什么?请记住,第一次调用闭包时,它会移动
s
,因此
s
现在没有有效值

根据您的具体需要,有几种方法可以实现这一点

  • 使闭包返回对字符串的引用

    注意:我们需要在
    转换表达式的右侧显式写出
    'a
    ,否则编译器会给出错误。我认为如果不引入中间函数(
    make_foo
    ),我们就无法编写正确的生命周期

  • 但是,由于
    FnBox
    不稳定,因此只能在夜间编译器中使用它。如果您想支持稳定的编译器,可以使用中定义的
    BoxFnOnce
    类型(尽管您需要显式地将闭包调用为
    x.call()
    x()
    将不起作用)

    error[E0277]: the trait bound `[closure@src/main.rs:5:24: 5:28 s:std::option::Option<std::string::String>]: std::ops::Fn<()>` is not satisfied
     --> src/main.rs:5:15
      |
    5 |     let foo = Box::new(|| s) as Box<Fn() -> Option<String>>;
      |               ^^^^^^^^^^^^^^ the trait `std::ops::Fn<()>` is not implemented for `[closure@src/main.rs:5:24: 5:28 s:std::option::Option<std::string::String>]`
      |
      = note: required for the cast to the object type `std::ops::Fn() -> std::option::Option<std::string::String>`
    
    error: aborting due to previous error
    
    fn make_foo<'a>(s: &'a Option<String>) -> Box<Fn() -> Option<&'a str> + 'a> {
        Box::new(move || s.as_ref().map(|s| &**s)) as Box<Fn() -> Option<&'a str> + 'a>
    }
    
    fn main() {
        let s = Some("xyz".to_string());
        let foo = make_foo(&s);
    
        println!("{:?}", foo());
    }
    
    #![feature(fnbox)]
    
    use std::boxed::FnBox;
    
    fn main() {
        let s = Some("xyz".to_string());
        let foo = Box::new(|| s) as Box<FnBox() -> Option<String>>;
    
        println!("{:?}", foo());
    }