为什么我不能在std :: env :: args迭代器上映射Path :: new?

时间:2018-06-15 23:18:47

标签: iterator rust

这有效:

@model IEnumerable<WebApplication3.Models.LiveRankingModel>

@{
    ViewData["Title"] = "LiveRanking";
}

<div style="text-align:center;">
    <h1><strong>Live Ranking</strong></h1>
</div>

<div style="display:flex; justify-content:space-around;">
    @foreach (var item in Model)
    {
    <div style="text-align: center; padding: 25px; border: 2px solid black; background-color: azure; border-radius: 25px; margin: 25px;">
        <div style="border:inherit;">
            <img src="data:image/jpg;base64,@System.Convert.ToBase64String(item.Image)" height="256" width="256" />
        </div>
        <hr />
        <h2>@item.Username</h2>
        <h3>@item.Score</h3>
    </div>
    }
</div>

这不起作用:

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 collect迭代器放入向量中以生成另一个迭代器?为什么我不能直接从另一个生成一个迭代器?

1 个答案:

答案 0 :(得分:4)

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

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

有效的代码不会在String上进行迭代,而是&String s;见What is the difference between iter and into_iter?。因此,在闭包中没有任何东西可以超出范围,并且从闭包返回引用是正常的。

正确的解决方案是将String数据的所有权转移到新类型。 PathBuf是合适的选择。 PathBuf&PathString&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