在 Rust 中为静态生命周期的悬挂引用和建议而苦苦挣扎

Struggling with dangling references and suggestions for static lifetimes in Rust

Rust-ing的菜鸟见谅。我编写了一个清理文件的函数,并验证了该函数的逻辑似乎没问题。然后我想将这个函数从 main 重命名为 helper 函数。我知道我可以在主函数中保留一些 IO 内容,但为了好玩,假设我想将下面的所有代码保留在辅助函数中。

如果我们将 return 类型更改为 Result<(), std::io::Error> 并将最后一行修改为 Ok(()),则下面的代码将编译。然而,这段代码没有。编译器建议我将 &str 修改为 &'static str,尽管此更改似乎无济于事,因为编译器随后会说 "E0277, main can only return types that implement termination"

在这一点上,由于对如何避免悬挂引用的理解不足,我开始崩溃。

fn main() -> Result<Vec<&str>, std::io::Error> {
    let file = File::open("22names.txt")?;
    let mut buf_reader = BufReader::new(file);
    let mut contents = String::new();
    buf_reader.read_to_string(&mut contents)?;

    contents.retain(|c| c != '"');
    let v: Vec<&str> = contents.split(',').collect();

    println!("first 10 indices of v are: {:?}", &v[..10]);

    Ok(v)
}

编辑:如果我修改以上内容,将 main 重命名为任意函数 f,并从新的 main 函数调用 f 并将结果赋给变量,let v = f() 我得到以下错误,这是由于 contents 超出范围这一事实造成的。如何将 contents 保持在范围内,或者更确切地说,是指向它的向量 v ? error[E0515]: 不能 return 引用局部变量 contents 的值,其中 contentsv 引用,我想要 return.

main 函数是程序的入口点。因为这个函数是第一个被执行的,没有其他函数调用过它。您的程序在主函数执行 return 后退出。 main 函数的 return 值用于确定程序的退出状态。因此,没有其他函数可以使用 main 的 return 值。我建议重命名您的函数。

另一个错误的发生是因为您 return 分割了一个字符串。 Content 包含您从文件中读取的数据,而 v 仅包含对该数据的引用。 content 超出范围后,内存将被释放。这将导致 v 包含无效指针。编译器不允许这样做。

您可以 return String 而不是 &strString 拥有基础数据。为此,您应该将函数签名更改为 fn helper() -> Result<Vec<String>, std::io::Error>。您需要将 Vec<&str> 转换为 Vec<String>。您可以像这样使用 String::from

let v: Vec<String> = contents.split(',').map(String::from).collect();