Rust 关闭工厂函数

标签 rust

我有一些 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 工作。我需要以某种方式复制。

最佳答案

错误表明 names 必须比静态生存期长,这是因为装箱的 Fn 具有静态生存期。您有两个选择:

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

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

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

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

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()
    })
}

关于Rust 关闭工厂函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38748054/

相关文章:

oop - 为什么 Rust 不支持特征对象向上转换?

rust - 将参数传递给函数n次

rust - 如何在不知道编译时结构的情况下读取CSV数据?

rust - 当输出值不属于类型时如何实现 std::ops::Index

rust - 为 HashMap 使用复杂键时如何避免临时分配?

rust - 借用 Rust 中的检查器和函数参数,正确还是过于热心?

rust - 如何在不移出参数的情况下实现 std::ops:{Add, Sub, Mul, Div} 运算符之一?

rust - 从另一个模块打印 vec 中的值 : field of struct is private

rust - 访问枚举变量字段的正确方法,该字段本身就是结构的字段

generics - 如何使用 `u32` 或 `&u32` 的任何迭代器编写通用函数?