有几个问题似乎与我遇到的问题有关 . 例如,请参见here和here . 基本上我正在尝试在本地函数中构建 String
,但随后将其作为 &str
返回 . 切片isn 't working because the lifetime is too short. I can' t直接在函数中使用 str
,因为我需要动态构建它 . 但是,我也不想返回 String
,因为它进入的对象的性质一旦构建就是静态的 . 有没有办法让我的蛋糕也吃?
这是一个最小的非编译复制:
fn return_str<'a>() -> &'a str {
let mut string = "".to_string();
for i in 0..10 {
string.push_str("ACTG");
}
&string[..]
}
3 回答
您可以选择 leak memory 将
String
转换为&'static str
:在许多情况下,这是一个非常糟糕的主意,因为每次调用此函数时内存使用量将永远增长 .
如果您希望每次调用都返回相同的字符串,请参阅:
不,你不能这样做 . 至少有两种解释为何如此 .
首先,请记住引用是借用的,即它们指向某些数据但不拥有它,它由其他人拥有 . 在这种特殊情况下,字符串(您要返回的切片)由函数拥有,因为它存储在局部变量中 .
当函数退出时,它的所有局部变量都被销毁;这涉及调用析构函数,
String
的析构函数释放字符串使用的内存 . 但是,您希望返回指向为该字符串分配的数据的借用引用 . 这意味着返回的引用立即变为悬空 - 它指向无效的内存!除此之外,还创建了Rust,以防止出现此类问题 . 因此,在Rust中,不可能返回指向函数局部变量的引用,这在C语言中是可能的 .
还有另一种解释,稍微更正式一些 . 我们来看看你的功能签名:
请记住,生命周期和泛型参数都是参数:它们由函数的调用者设置 . 例如,某些其他函数可能会像这样调用它:
这需要
'a
为'static
,但它当然是不可能的 - 您的函数不会返回对静态内存的引用,它会返回一个具有严格较小生命周期的引用 . 因此,这样的函数定义是不合理的,并且被编译器禁止 .无论如何,在这种情况下,你需要返回一个拥有类型的值,在这种特殊情况下,它将是一个拥有的
String
:在某些情况下,您将传递一个字符串切片,并可能有条件地想要创建一个新字符串 . 在这些情况下,您可以返回Cow . 这允许在可能的情况下引用并且拥有
String
否则: