gpt4 book ai didi

function - 你如何返回不可复制的类型?

转载 作者:行者123 更新时间:2023-11-29 07:47:36 24 4
gpt4 key购买 nike

我试图了解您如何返回非基元(即不实现 Copy 的类型)。如果您返回类似于 i32 的内容,则该函数会在内存中创建一个新值以及返回值的副本,因此它可以在函数范围之外使用。但是,如果您返回一个未实现 Copy 的类型,则它不会执行此操作,并且您会收到所有权错误。

我曾尝试使用 Box 在堆上创建值,以便调用者可以获得返回值的所有权,但这似乎也不起作用。

也许我以错误的方式解决了这个问题,使用了我在 C# 或其他语言中使用的相同编码风格,其中函数返回值,而不是将对象引用作为参数传递并对其进行修改,这样您就可以在 Rust 中轻松指示所有权。

以下代码示例编译失败。我认为问题仅出在迭代器闭包中,但我已经包含了整个函数以防万一我看不到任何东西。

pub fn get_files(path: &Path) -> Vec<&Path> { 
let contents = fs::walk_dir(path);

match contents {
Ok(c) => c.filter_map(|i| { match i {
Ok(d) => {
let val = d.path();
let p = val.as_path();
Some(p)
},
Err(_) => None } })
.collect(),
Err(e) => panic!("An error occurred getting files from {:?}: {}", pa
th, e)
}
}

编译器给出以下错误(我已删除所有行号和无关文本):

error: `val` does not live long enough
let p = val.as_path();
^~~
in expansion of closure expansion
expansion site
reference must be valid for the anonymous lifetime #1 defined on the block...
...but borrowed value is only valid for the block suffix following statement
let val = d.path();
let p = val.as_path();
Some(p)
},

最佳答案

您通过...返回一个值,返回它。但是,您的签名表明您正试图返回一个对值的引用。当对象将在 block 的末尾被删除时,您不能这样做,因为引用将变得无效。

在你的情况下,我可能会写类似的东西

#![feature(fs_walk)]

use std::fs;
use std::path::{Path, PathBuf};

fn get_files(path: &Path) -> Vec<PathBuf> {
let contents = fs::walk_dir(path).unwrap();
contents.filter_map(|i| {
i.ok().map(|p| p.path())
}).collect()
}

fn main() {
for f in get_files(Path::new("/etc")) {
println!("{:?}", f);
}
}

主要是函数返回一个Vec<PathBuf>拥有路径的类型的集合,并且不仅仅是对其他人内存的引用。

在您的代码中,您执行 let p = val.as_path() .在这里,val PathBuf .然后你打电话as_path ,定义为:fn as_path(&self) -> &Path .这意味着给出对 PathBuf 的引用,您可以获得对 Path 的引用它的生命周期与 PathBuf 一样长将。但是,您试图将该引用保留的时间超过 vec。将存在,因为它将在迭代结束时被删除。

关于function - 你如何返回不可复制的类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32040312/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com