创建 Vec 时借用的值存在的时间不够长

2023-12-28

编者注:这个问题是在 Rust 1.0 之前提出的。从那时起,许多函数和类型都发生了变化,某些语言语义也发生了变化。问题中的代码不再有效,但答案中表达的想法可能有效。

我正在尝试列出目录中的文件并将文件名复制到我自己的目录中Vec。我尝试了几种解决方案,但最终总是会遇到无法创建足够长的生存变量的问题。我不明白我的错误。

fn getList(action_dir_path : &str) -> Vec<&str> {
    let v = fs::readdir(&Path::new(action_dir_path))
            .unwrap()
            .iter()
            .map(|&x| x.filestem_str().unwrap())
            .collect();
    return v;
}

为什么编译器会抱怨“x”?我不在乎 x,我想要&str在里面我想&str是静态的。

我尝试了这种方法,但得到了相同的结果,编译器抱怨“路径”寿命不够长。

fn getList2(action_dir_path : &str) -> Vec<&str> {
    let paths = fs::readdir(&Path::new(action_dir_path)).unwrap();
    let mut v : Vec<&str> = Vec::new();

    for path in paths.iter(){
       let aSlice = path.filestem_str().unwrap();
       v.push(aSlice);
    }

    return v;
}

Here is .


支持 Rust 1.0 的代码最直译是这样的:

use std::{fs, path::Path, ffi::OsStr};

fn getList(action_dir_path: &str) -> Vec<&OsStr> {
    let v = fs::read_dir(&Path::new(action_dir_path))
        .unwrap()
        .map(|x| x.unwrap().path().file_stem().unwrap())
        .collect();
    return v;
}

这会产生错误消息:

铁锈 2015

error[E0597]: borrowed value does not live long enough
 --> src/lib.rs:6:18
  |
6 |         .map(|x| x.unwrap().path().file_stem().unwrap())
  |                  ^^^^^^^^^^^^^^^^^                    - temporary value only lives until here
  |                  |
  |                  temporary value does not live long enough
  |
note: borrowed value must be valid for the anonymous lifetime #1 defined on the function body at 3:1...
 --> src/lib.rs:3:1
  |
3 | / fn getList(action_dir_path: &str) -> Vec<&OsStr> {
4 | |     let v = fs::read_dir(&Path::new(action_dir_path))
5 | |         .unwrap()
6 | |         .map(|x| x.unwrap().path().file_stem().unwrap())
7 | |         .collect();
8 | |     return v;
9 | | }
  | |_^

铁锈 2018

error[E0515]: cannot return value referencing temporary value
 --> src/lib.rs:6:18
  |
6 |         .map(|x| x.unwrap().path().file_stem().unwrap())
  |                  -----------------^^^^^^^^^^^^^^^^^^^^^
  |                  |
  |                  returns a value referencing data owned by the current function
  |                  temporary value created here

问题来自于Path::file_stem https://doc.rust-lang.org/std/path/struct.Path.html#method.file_stem。这是签名:

pub fn file_stem(&self) -> Option<&OsStr>

这表明该方法将返回一个借用参考OsStr. The PathBuf结构是owner字符串的。当你离开该方法时,就没有任何地方可以拥有该方法了PathBuf,所以它会被丢弃。这意味着任何对PathBuf将不再有效。这是 Rust 阻止您引用不再分配的内存,对 Rust 来说是的!

你能做的最简单的事情就是返回一个Vec<String>. String拥有其中的字符串,所以我们不需要担心当我们离开函数时它会被释放:

fn get_list(action_dir_path: &str) -> Vec<String> {
    fs::read_dir(action_dir_path)
        .unwrap()
        .map(|x| {
            x.unwrap()
                .path()
                .file_stem()
                .unwrap()
                .to_str()
                .unwrap()
                .to_string()
        })
        .collect()
}

我还更新了样式(免费!),使其更像 Rust:

  1. Use snake_case对于物品
  2. 类型定义中冒号前不能有空格
  3. 没有理由设置一个变量只是为了返回它。
  4. 不要使用显式的return语句,除非您提前退出函数。
  5. 无需将路径包装在Path.

然而,我并不喜欢所有的拆包。我会这样写这个函数:

use std::{ffi::OsString, fs, io, path::Path};

fn get_list(action_dir_path: impl AsRef<Path>) -> io::Result<Vec<OsString>> {
    fs::read_dir(action_dir_path)?
        .map(|entry| entry.map(|e| e.file_name()))
        .collect()
}

fn main() {
    println!("{:?}", get_list("/etc"));
}

除了上述更改外:

  1. 我使用通用类型作为输入路径。
  2. 我返回一个Result将错误传播给调用者。
  3. 我直接问DirEntry为文件名。
  4. 我将类型保留为OsString.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

创建 Vec 时借用的值存在的时间不够长 的相关文章

随机推荐

  • 将 Vue 组件暴露给外部项目

    我正在尝试探索如何将我的 Vue 组件公开给其他项目而不发布到 NPM 我可以找到以下链接 其中显示了如何将 Vue 组件发布到 NPM 如何在 npm 62b67dfb3e58 上发布您的 vue js 组件 https medium c
  • WPF中上标的上标

    我已经设法使用以下代码行创建字符上标 Paragraph p new Paragraph Span s new Span s BaselineAlignment BaselineAlignment Superscript s Inlines
  • 使用 XML 序列化时是否有办法避免自闭合标签?

    我正在使用 VB NET 但遇到 XML 序列化问题 当我正在序列化的对象中存在空值时 XML 文件包含以下标签
  • Python3 写入文件 beautifulsoup

    我希望用以下代码编写 beautifulsoup 表单 soup BeautifulSoup con content f open Desktop littletext rtf w f write str soup f close 我收到此
  • 从 Web 视图中的链接打开 Mobile Safari

    是否有 URI 方案可将 Mobile Safari 打开到特定 URL e g a href Open Google in Safari a Update 因此 从 iOS 6 0 2 开始 仍然没有特定于 MobileSafari 的
  • 尝试附加附件通过 request.post 发送时,表单数据库抛出无法读取 null 属性的错误

    当我尝试制作一个request post with form data对于附件 我收到以下错误 该错误来自表单数据库 var filename options filename value name value path TypeError
  • 直接使用 ld 链接 C 程序失败,未定义对“__libc_csu_fini”的引用

    我正在尝试在Linux下编译C程序 然而 出于好奇 我尝试手动执行一些步骤 我使用 gcc 前端生成汇编代码 然后运行GNU汇编器来获取目标文件 然后将其与 C 运行时链接以获得可工作的可执行文件 现在我被链接部分困住了 该程序是一个非常基
  • 如何使用 python 获取文件的扩展 MacOS 属性?

    我有兴趣使用 python 从文件中获取更多信息 我知道使用 os stat 如下所示 会返回有关文件的信息 但我想从文件中获取其他属性 例如 来自哪里 os stat filename posix stat result st mode
  • 如何从 C 代码中获取单操作数 imul

    我必须用 C 语言编写什么才能让汇编器显示imul与一个操作数 例如 imul ebp 如果你想编写 C 代码以便编译器发出imul对于一个操作数 唯一的方法是使用扩大有符号乘法 即将操作数转换为有符号类型寄存器长度的两倍 因此 在 32
  • 单选按钮被选中的事件?

    是否有一些单选按钮被选择的事件 我知道我可以使用 单击 但我相信可以在某些浏览器中设置单选按钮的样式 这样单击单选按钮的外部区域可能不会选择该单选按钮 我应该使用什么事件 这取决于您想何时获知该事件 如果您想立即了解 请前往click IE
  • java中向上转换的内存分配

    考虑这些类 public class Animal public class Dog extends Animal public AnimalTest public static void main String args Dog d ne
  • 将 Stripe 与 Devise 结合使用以实现 Ruby on Rails 订阅

    我正在尝试将 Stripe 的定期支付系统与 Devise 集成 使用 Ryan 最近的 Railscast 作为指南 http railscasts com episodes 288 billing with stripe view as
  • Blend“WPF 项目不支持窗口”

    我对 Blend 报告 Windows Presentation Foundation WPF 项目不支持窗口 感到沮丧 由于无法构建的配置 但无法完全弄清楚如何摆脱它 我发现这可能是由于我尝试使用 x86 和 x64 配置的单一解决方案
  • 二进制可执行文件是可移植的

    编译 C 程序后 我可以获取二进制可执行文件 并在另一个没有加载 gcc 的系统 例如 Ubuntu 系统 上运行它吗 技术上 是的 但如果您需要最大的可移植性 请使用静态链接 严格来说你不需要gcc 但你可能需要各种库 默认情况下 语言处
  • CSS 将所选文本的一部分向右对齐[重复]

    这个问题在这里已经有答案了 这是我的 HTML 的样子
  • 如何使两个按钮并排且响应灵敏?

    我有一个小任务 在使用桌面时需要并排两个按钮 然后在移动设备上它们堆叠在一起但尺寸没有减小 我已经设法将它们堆叠在一起 但它们的大小不同 每当我定义按钮的 大小时 它们都会挤在一起 在设备视图中看起来很丑陋 button backgroun
  • 动画系统的神经网络大小

    我决定使用神经网络来为我拥有的动画引擎创建行为 神经网络为我身体的每个部位接收 3 个向量和 1 个欧拉角 第一个向量 3 是位置 第二个向量是速度 第三个向量是角速度 欧拉角是身体部位的旋转角度 我的身体有 7 个部位 这些数据类型中的每
  • SQL:仅比较日期与月份和年份列

    我有一张桌子MonthlyShipments看起来像 partnumber quantity month year part1 12 6 2011 part1 22 5 2011 part1 32 4 2011 part1 42 3 201
  • Linux fedora tc qdisc 出现“错误:未找到指定的 qdisc”。

    我正在尝试在 Linux fedora 上运行以下命令 sudo tc qdisc add dev enp2s0 handle 1 0 root netem delay 0 loss 1 我检查了接口 enp2s0 并且设置正常 但我收到以
  • 创建 Vec 时借用的值存在的时间不够长

    编者注 这个问题是在 Rust 1 0 之前提出的 从那时起 许多函数和类型都发生了变化 某些语言语义也发生了变化 问题中的代码不再有效 但答案中表达的想法可能有效 我正在尝试列出目录中的文件并将文件名复制到我自己的目录中Vec 我尝试了几