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

如何在Rust中按值返回结构?,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(&arg

我正在学习生锈,在第一步就失败了。。。我有下一个功能:

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;
}
使用std::env;
使用std::path::path;
fn get_path()->path{
让args:Vec=env::args().collect();
断言!(!args.is_empty(),“需要目标路径!”);
让path=path::new(&args[0]);
断言!(path.exists(),“目标路径不存在!”);
断言!(path.is_dir(),“目标路径不是目录!”);
返回路径;
}
这是一个非常简单的函数,但是
path
是一个引用,我不知道如何通过值从函数返回
path
对象?或者如何返回在外部函数上下文中处于活动状态的引用


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

严格地说,
路径
不是一个引用,它是一个非大小的类型,只能存在于引用后面,事实上。因此,它与为函数添加注释的路径不兼容

事实上,这是编译错误告诉您的两件事,当发布锈迹代码时,您确实想给人们提供编译错误(或复制案例),因为一旦您习惯了这些错误,这些错误的信息将非常丰富:

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
  |
表示您返回的是不允许的非大小类型),并且

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

无论如何,
Path
的拥有/结构版本是,因此您应该返回该版本,并将您的
Path
转换为
PathBuf
,或者首先创建一个
PathBuf
,例如

使用std::env;
使用std::path::PathBuf;
fn get_path()->PathBuf{
让args:Vec=env::args().collect();
断言!(!args.is_empty(),“需要目标路径!”);
let path=PathBuf::from(&args[0]);
断言!(path.exists(),“目标路径不存在!”);
断言!(path.is_dir(),“目标路径不是目录!”);
路径
}
顺便说一下

可能不是您期望或想要的:正如
std::env::args
的文档所述:

第一个元素通常是可执行文件的路径

而这并不是一个锈迹已被视为适合与底层系统分离的领域

您可能希望改为使用
args[1]
,或者使用更高级别的args解析API


另一个旁白与Sven Marnach对您的问题的评论有关:调用
path.exists
然后调用
path.is_dir
需要获取元数据两次(我认为Rust不会缓存此信息)。效率方面在这里可能不是最原始的,但您可能仍然希望显式地使用
Path::metadata
,然后询问if
是否为dir
Path::metadata
将返回
Err
,如果路径不是有效的磁盘对象)。

严格来说,
Path
不是一个引用,它是一种不加大小的类型,只能存在于引用后面,实际上也是。因此,它与为函数添加注释的路径不兼容

事实上,这是编译错误告诉您的两件事,当发布锈迹代码时,您确实想给人们提供编译错误(或复制案例),因为一旦您习惯了这些错误,这些错误的信息将非常丰富:

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
  |
表示您返回的是不允许的非大小类型),并且

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

无论如何,
Path
的拥有/结构版本是,因此您应该返回该版本,并将您的
Path
转换为
PathBuf
,或者首先创建一个
PathBuf
,例如

使用std::env;
使用std::path::PathBuf;
fn get_path()->PathBuf{
让args:Vec=env::args().collect();
断言!(!args.is_empty(),“需要目标路径!”);
let path=PathBuf::from(&args[0]);
断言!(path.exists(),“目标路径不存在!”);
断言!(path.is_dir(),“目标路径不是目录!”);
路径
}
顺便说一下

可能不是您期望或想要的:正如
std::env::args
的文档所述:

第一个元素通常是可执行文件的路径

而这并不是一个锈迹已被视为适合与底层系统分离的领域

您可能希望改为使用
args[1]
,或者使用更高级别的args解析API


另一个旁白与Sven Marnach对您的问题的评论有关:调用
path.exists
然后调用
path.is_dir
需要获取元数据两次(我认为Rust不会缓存此信息)。效率方面在这里可能不是最原始的,但是您可能仍然希望显式地使用
Path::metadata
,然后询问if
是否为dir
Path::metadata
将返回
Err
,如果路径不是有效的磁盘对象)。

:“[
Path
]是一个未分级的类型,这意味着它必须始终在
&
或之类的指针后面使用。有关此类型的自有版本,请参阅。“The
assert!()
macro,或者更一般地说,恐慌是用来处理编程错误的,而目录不存在则是运行时错误。通过返回
结果
@HTNW,可以更好地处理运行时错误,谢谢您的支持explanation@SvenMarnach,谢谢,我会解决它:“[
路径
]是一个未大小的类型,这意味着它必须始终在
&
或之类的指针后面使用。有关此类型的自有版本,请参阅。
断言!()
macro,或者更一般地说,恐慌是用来处理编程错误的,而目录不存在则是运行时错误。通过返回
结果
@HTNW,可以更好地处理运行时错误,谢谢您的支持explanation@SvenMarnach,谢谢,我会的
Path::new(&args[0]);