在Rust的2个Vec中具有相同的字符串?

jjhzyzn0  于 2022-12-19  发布在  其他
关注(0)|答案(1)|浏览(117)

不确定这是否是我问题的最佳标题,如果有更好的,请建议。
这是一个工作代码的例子,这是我的真实的代码的近似,但它是很好的演示。

fn main() {
    let data = vec!["a".to_string(), "b".to_string(), "c".to_string(), ];
    
    let mut v1 = Vec::new();
    let mut v2 = Vec::new();
    for i in data {
        v1.push(i.to_owned());
        v2.push(i.to_owned());
    }
    // to make it read-only, so that I do not make same stupid mistake later
    let v1 = v1;
    let v2 = v2;
    
    println!("{:?}", v1);
    println!("{:?}", v2);
}

基本上我有字符串的向量,我需要N个(已经有2个了,但是会有更多,大约20个)向量,这些向量需要从原始向量访问字符串。
我有一个解决方案是使用to_owned()。如果我理解正确的话,这基本上是创建String的副本,所以我最终在内存中有2个相同的String,我发现这是不必要的浪费,希望避免它。

在Rust,最好的方法是什么

我发现的一个解决方案是将原始数据Vec转换为&str,但不确定这是否是Rust中最好/正确的方法(我仍然是Rust的初学者)。

ttisahbt

ttisahbt1#

如果没有更多的上下文来说明为什么需要这些向量,或者您想用它们做什么,我认为您可以采取两种方法。
1.使用参考资料
这种方法将字符串存储在data变量中一次,并将对这些字符串的引用存储在其他向量中。

fn main() {
    let data = vec!["a".to_string(), "b".to_string(), "c".to_string(), ];
    
    let mut v1 = Vec::new();
    let mut v2 = Vec::new();
    for i in &data {
        v1.push(i);
        v2.push(i);
    }
    // to make it read-only, so that I do not make same stupid mistake later
    let v1 = v1;
    let v2 = v2;
    
    println!("{:?}", v1);
    println!("{:?}", v2);
}

1.使用引用计数智能指针
这种方法将字符串存储在堆中,并使用标准库中的Arc类型,通过引用计数确保在删除所有向量后删除堆中的字符串。克隆操作的开销很小,它只会增加引用计数。

use std::sync::Arc;

fn main() {
    let data = ["a".to_string(), "b".to_string(), "c".to_string()]
        .into_iter().map(|i| Arc::new(i)).collect::<Vec<_>>();
    
    let mut v1 = Vec::new();
    let mut v2 = Vec::new();
    for i in &data {
        v1.push(Arc::clone(i));
        v2.push(Arc::clone(i));
    }
    // to make it read-only, so that I do not make same stupid mistake later
    let v1 = v1;
    let v2 = v2;
    
    println!("{:?}", v1);
    println!("{:?}", v2);
}

相关问题