【问题标题】:Why can't I map Path::new over the std::env::args iterator?为什么我不能将 Path::new 映射到 std::env::args 迭代器上?
【发布时间】:2018-06-15 23:18:46
【问题描述】:

这行得通:

let paths: Vec<String> = args.collect();
let paths = paths.iter().map(|f| std::path::Path::new(&f));

这不起作用:

let paths = ::std::env::args().map(|f| std::path::Path::new(&f));
error[E0597]: `f` does not live long enough
 --> src/main.rs:2:66
  |
2 |     let paths = ::std::env::args().map(|f| std::path::Path::new(&f));
  |                                                                  ^-- borrowed value needs to live until here
  |                                                                  ||
  |                                                                  |`f` dropped here while still borrowed
  |                                                                  borrowed value does not live long enough

为什么我需要将collectargs 迭代器放入一个向量中,只是为了产生另一个迭代器?为什么我不能直接从另一个迭代器生成一个迭代器?

【问题讨论】:

  • 你很可能想要PathBuf,而不是Path
  • PathBuf 是可变的。我在这里不需要可变性。为什么你认为我需要PathBuf

标签: iterator rust


【解决方案1】:

Args 迭代器返回 String 类型的值。当您 map 遍历迭代器时,闭包将获得每个值的所有权。

不起作用的代码尝试引用String,但该字符串将在闭包结束时超出范围。如Return local String as a slice (&str) 中所述,这是不允许的。

有效的代码不是迭代Strings,而是&amp;Strings;见What is the difference between iter and into_iter?。因此,在闭包中没有什么可以超出范围,从闭包返回引用就可以了。

正确的解决方案是将String 数据的所有权转移到新类型。 PathBuf 是合适的选择。 PathBuf&amp;Path 就像 String&amp;str

let paths = ::std::env::args().map(std::path::PathBuf::from);

PathBuf 是可变的。我在这里不需要可变性。为什么你认为我需要PathBuf

您对可变性在 Rust 中的工作方式感到困惑。回去重新阅读The Rust Programming Language,尤其是Variables and Mutability的章节。

Rust 中的类型本身不是可变的或不可变的。可变性是变量绑定的一个属性

let buf = std::path::PathBuf::new();
buf.push("home");
error[E0596]: cannot borrow immutable local variable `buf` as mutable
 --> src/main.rs:3:5
  |
2 |     let buf = std::path::PathBuf::new();
  |         --- consider changing this to `mut buf`
3 |     buf.push("home");
  |     ^^^ cannot borrow mutably

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-10-27
    • 2018-05-06
    • 1970-01-01
    • 2021-01-19
    • 2013-08-26
    • 2018-12-02
    • 2016-08-30
    • 1970-01-01
    相关资源
    最近更新 更多