如何在 Rust 中按值返回结构?

Шах*_*Шах 1 rust

我正在学习 Rust 并且已经在第一步失败了......我有下一个功能:

use std::env;
use std::path::Path;

fn get_path() -> Path {
    let args: Vec<String> = env::args().collect();
    assert!(!args.is_empty(), "Target path is required!");
    let path = Path::new(&args[0]);
    assert!(path.exists(), "Target path doesn't exist!");
    assert!(path.is_dir(), "Target path is not a directory!");
    return path;
}
Run Code Online (Sandbox Code Playgroud)

path是一个非常简单的函数,但它是一个引用,我不知道如何Path按值从函数返回对象?或者如何返回将在外部函数上下文中存活的引用?

PS我寻找了类似的问题,但不幸的是我没有得到它。

Mas*_*inn 5

严格来说,Path它不是一个引用,而是一个无大小的类型,它只能存在一个引用后面,并且确实Path::new返回&PathnotPath。因此,这-> Path与您为函数注释的不兼容。

这些实际上是编译错误告诉您的两件事,并且您真的希望在发布 Rust 代码时向人们提供编译错误(或复制案例),因为一旦您习惯了这些错误,这些错误就会提供非常丰富的信息:

error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
 --> src/lib.rs:4:18
  |
4 | fn get_path() -> Path {
  |                  ^^^^ borrow the `Path` instead
  |
Run Code Online (Sandbox Code Playgroud)

说您返回的是不允许的未调整大小的类型),并且

error[E0308]: mismatched types
  --> src/lib.rs:10:12
   |
4  | fn get_path() -> Path {
   |                  ---- expected `std::path::Path` because of return type
...
10 |     return path;
   |            ^^^^ expected struct `std::path::Path`, found `&std::path::Path`
Run Code Online (Sandbox Code Playgroud)

说明您要返回的类型与您要返回的值的类型不匹配。

无论如何,作为notes的官方文档PathPathis的拥有/结构版本PathBuf,因此您应该返回它,并将您的转换Path为 a PathBuf,或者实际上只是首先创建 a PathBuf,例如

error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
 --> src/lib.rs:4:18
  |
4 | fn get_path() -> Path {
  |                  ^^^^ borrow the `Path` instead
  |
Run Code Online (Sandbox Code Playgroud)

顺便,

Path::new(&args[0]);
Run Code Online (Sandbox Code Playgroud)

可能不是您期望或想要的:作为std::env::args注释的文档:

第一个元素传统上是可执行文件的路径

这不是 Rust 认为适合与底层系统分离的领域。

您可能想要args[1],或者使用更高级别的 args 解析 API。

另一边与 Sven Marnach 对您的问题的评论有关:调用path.existsthenpath.is_dir需要两次获取元数据(我认为 Rust 不会缓存此信息)。效率方面在这里可能不是原始的,但您可能仍然想明确使用Path::metadata,然后询问if (如果路径不是有效的磁盘上的东西则返回一个)。is_dirPath::metadataErr

  • 您可能想要执行“env::args().nth(1)”,而不是将“env::args()”收集到向量中,然后索引到向量中。 (3认同)