Rust指定局部变量的生命周期

5

我对Rust不太熟悉,对生命周期标志符的概念仍然有疑问。

我有一个引用的Vec(或任何其他集合)。 现在我想用对新创建的本地变量的另一个引用替换特定引用。 现在的问题是,本地新变量的生命周期比向量短,这将使引用无效。

以下是试图实现我的示例代码,但会抛出编译时错误:

fn main() {
    let values = ["one".to_string(), "lorem".to_string(), "three".to_string()];
    let borrowed_values = vec![&values[0], &values[1], &values[2]];
    println!("{:?}", do_the_impossible(borrowed_values));
}

fn do_the_impossible(mut data: Vec<&String>) -> Vec<&String> {
    let replacement = "two".to_string();
    data[1] = &replacement;
    return data;
}

问题现在是:我如何创建与向量相同生命周期的新变量?
我想使用引用,因为克隆对象会非常昂贵。
我的初始想法是使用生命周期说明符,指示本地变量应与向量一样长寿。但我找不到语法正确的方式来做到这一点。是否有可能指定本地变量的生命周期?
如果不行,有没有其他方法可以避免克隆向量的元素? 我最后的选择将是使用 `Rc` 指针。
提前感谢!

1
这回答解决了你的问题吗?有没有办法返回在函数中创建的变量的引用? 简而言之:不,无论是在Rust还是在任何语言中都不能这样做。请返回一个拥有的值。 - trent
2
我想使用引用,因为克隆对象的成本相当高昂。这是 Rust 新手经常犯的错误。因为你返回一个拥有所有权的东西,并不意味着它会被克隆。例如,String 是一种拥有 str 的类型,但即使你有一个长度为一兆字节的 String,从函数中返回它只会最多复制 24 个字节(对于任何 Vec 也是如此)。 - trent
也许我们之间存在误解,函数返回一个拥有所有权的Vec。但原始的Vec并不拥有其值的所有权。我想返回一个有效的Vec,其中仅更改了一个值,原始Vec保持不变,并且尽可能少地进行克隆。 - Pilikio
1个回答

5
这似乎是使用 std::borrow::Cow 的一个典型场景,它可以让你拥有一个值,该值可以由借用或拥有的值支持。
你可以这样编写代码:
use std::borrow::Cow;

fn main() {
    let values = ["one".to_string(), "lorem".to_string(), "three".to_string()];
    let borrowed_values: Vec<_> = values.iter().map(Cow::Borrowed).collect();
    println!("{:?}", do_the_impossible(borrowed_values));
}

fn do_the_impossible<'a>(mut data: Vec<Cow<'a, String>>) -> Vec<Cow<'a, String>> {
    let replacement = "two".to_string();
    data[1] = Cow::Owned(replacement);
    return data;
}

只是为了确认我没有误解什么: 如果在 do_the_impossible() 调用之后调用 borrowed_values.clone()。这些值(字符串)是被复制还是只是引用(Cow)?如果 Cow 元素中有一个是 Cow::Owned 呢?这个值会被克隆还是借用? - Pilikio
我们可以通过查看CowClone实现找到答案:https://doc.rust-lang.org/src/alloc/borrow.rs.html#185-202 - 如果基础值是一个借用,则它将是另一个借用;如果基础值是一个所有权,则克隆它。如果您希望不同的语义,您也可以实现自己的Cow版本-它只是一个实现了一些有用特性和函数的enum :) - Daniel Wagner-Hall
好的,谢谢。看起来这非常接近我想要的,可以进行微调以完全解决我的问题。 - Pilikio

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接