【问题标题】:Rust closures from factory functions工厂函数的 Rust 闭包
【发布时间】:2016-08-03 15:37:50
【问题描述】:

我有一些 Rust 代码正在尝试使用,但我不知道如何去做。

fn main() {
    let names = vec!["foo", "bar", "baz"];
    let print = printer(names);
    let result = print();
    println!("{}", result);
    do_other_thing(names.as_slice());
}

fn printer(names: Vec<&str>) -> Box<Fn() -> String> {
    Box::new(move || {
        let text = String::new();
        for name in names {
            text = text + name;
        }
        text
    })
}

fn do_other_thing(names: &[&str]) {}

编译为:

error[E0477]: the type `[closure@src/main.rs:10:14: 16:6 names:std::vec::Vec<&str>]` does not fulfill the required lifetime
  --> src/main.rs:10:5
   |
10 |       Box::new(move || {
   |  _____^ starting here...
11 | |         let text = String::new();
12 | |         for name in names {
13 | |             text = text + name;
14 | |         }
15 | |         text
16 | |     })
   | |______^ ...ending here
   |
   = note: type must outlive the static lifetime

我对正在发生的事情有一个模糊的概念。看起来闭包有可能比names 参数更长寿。我可以注释为 'static 但这感觉不对,即使这样我也不想移动向量以便 do_other_thing 工作。我需要以某种方式复制。

【问题讨论】:

    标签: rust


    【解决方案1】:

    错误说names 必须比静态生命周期更长,这是因为装箱的Fn 具有静态生命周期。你有两个选择:

    1. 'static 生命周期添加到names

      fn printer(names: Vec<&'static str>) -> Box<Fn() -> String>{
          Box::new(move|| {
              // ...
          })
      }
      
    2. 更改装箱的Fn 的生命周期以匹配names 的生命周期:

      fn printer<'a>(names: Vec<&'a str>) -> Box<Fn() -> String + 'a>{
          Box::new(move|| {
              // ...
          })
      }
      

    请注意,闭包的主体需要调整,并且您将names 的所有权授予printer,因此您不能在do_other_thing 中使用names。这是一个固定版本:

    fn main() {
        let names = vec!["foo", "bar", "baz"];
        let print = printer(&names);
        let result = print();
        println!("{}", result);
        do_other_thing(names.as_slice());
    }
    
    fn printer<'a>(names: &'a Vec<&str>) -> Box<Fn() -> String + 'a>{
        Box::new(move || {
            // this is more idiomatic
            // map transforms &&str to &str
            names.iter().map(|s| *s).collect()
        })
    }
    

    【讨论】:

    • 谢谢!与闭包生命周期相关的 + 'a 正是我想要的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-22
    • 1970-01-01
    相关资源
    最近更新 更多