如何将返回字符串的迭代器转换为可以传递给&[&str]的函数?我试图将迭代器映射到超过&str秒的迭代器,但我得到一个错误:

error[E0515]: cannot return reference to function parameter `s`
  --> src/main.rs:89:52
   |
89 |     let args: Vec<&str> = std::env::args().map(|s| s.as_str()).collect();
   |                                                    ^^^^^^^^^^ returns a reference to data owned by the current function

为什么会出现这个错误?args是main中的一个局部变量,因此它的生存期肯定会延长到函数的末尾,因此在整个parse_args调用过程中都是有效的.

如果函数应该采用不同的类型,我可以更改它,但我的印象是这种类型对我的目的是正确的-我不需要拥有对向量的访问权限,也不需要拥有对值的访问权限.

以下是重现错误的代码:

fn main() {
    let args: Vec<&str> = std::env::args().map(|s| s.as_str()).collect();
    let config = parse_args(&args);
    // do stuff with config
}


fn parse_args(args: &[&str]) {
// parse args
}

推荐答案

您需要两次使用collect(),首先是Vec<String>,然后迭代,然后将collect()迭代为Vec<&str>:

let args: Vec<String> = std::env::args().collect();
let args: Vec<&str> = args.iter().map(|v| v.as_str()).collect();

let config = parse_args(&args);

这是因为std::env::args()返回超过String的迭代器.如果你将它们转换成&str,当我们调用下一个物品时,它们就会被丢弃,该死的!你的&str在摇晃.

所以我们需要一个地方来存储String,然后因为我们需要&[&str]而不是&[String],所以我们需要迭代它并再次收集它.

然而,请注意, Select &[String]是完全正常的.与&String不同,which is basically useless-&str总是更灵活,这在间接指令(如&[String]&[&str])之后并非如此,正是因为我们现在看到的情况.

如果您想要最大限度地允许(例如,对于公共函数),您可以使用&[impl AsRef<str>].这将允许两者兼而有之.然后,当您使用数据时,您需要使用as_ref()将其转换为&str.

Rust相关问答推荐

as操作符如何将enum转换为int?

访问Rust中的隐藏变量

抽象RUST中的可变/不可变引用

在Rust中显式装箱受生存期限制的转换闭包

integer cast as pointer是什么意思

使用极点数据帧时,找不到枚举结果的方法lazy()

`RwLockWriteGuard_,T`不实现T实现的特征

在Rust中声明和定义一个 struct 体有什么区别

为什么Deref类特征不构成?

为什么需要静态生命周期以及在处理 Rust 迭代器时如何缩小它?

为什么我们有两种方法来包含 serde_derive?

Rust 异步循环函数阻塞了其他future 任务的执行

是否可以通过可变引用推进可变切片?

从 Axum IntoResponse 获取请求标头

使用 `clap` 在 Rust CLI 工具中设置布尔标志

&str 的编译时拆分是否可能?

字符串切片的向量超出范围但原始字符串仍然存在,为什么判断器说有错误?

有没有办法阻止 rust-analyzer 使非活动代码变暗?

相交着色器从 SSBO 中读取零

如果我立即等待,为什么 `tokio::spawn` 需要一个 `'static` 生命周期?