在 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
的值,其中 contents
被 v
引用,我想要 return.
main 函数是程序的入口点。因为这个函数是第一个被执行的,没有其他函数调用过它。您的程序在主函数执行 return 后退出。 main 函数的 return 值用于确定程序的退出状态。因此,没有其他函数可以使用 main
的 return 值。我建议重命名您的函数。
另一个错误的发生是因为您 return 分割了一个字符串。 Content
包含您从文件中读取的数据,而 v
仅包含对该数据的引用。 content
超出范围后,内存将被释放。这将导致 v
包含无效指针。编译器不允许这样做。
您可以 return String
而不是 &str
。 String
拥有基础数据。为此,您应该将函数签名更改为 fn helper() -> Result<Vec<String>, std::io::Error>
。您需要将 Vec<&str>
转换为 Vec<String>
。您可以像这样使用 String::from
:
let v: Vec<String> = contents.split(',').map(String::from).collect();
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
的值,其中 contents
被 v
引用,我想要 return.
main 函数是程序的入口点。因为这个函数是第一个被执行的,没有其他函数调用过它。您的程序在主函数执行 return 后退出。 main 函数的 return 值用于确定程序的退出状态。因此,没有其他函数可以使用 main
的 return 值。我建议重命名您的函数。
另一个错误的发生是因为您 return 分割了一个字符串。 Content
包含您从文件中读取的数据,而 v
仅包含对该数据的引用。 content
超出范围后,内存将被释放。这将导致 v
包含无效指针。编译器不允许这样做。
您可以 return String
而不是 &str
。 String
拥有基础数据。为此,您应该将函数签名更改为 fn helper() -> Result<Vec<String>, std::io::Error>
。您需要将 Vec<&str>
转换为 Vec<String>
。您可以像这样使用 String::from
:
let v: Vec<String> = contents.split(',').map(String::from).collect();