Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Having same String in 2 Vec in Rust?

Not sure if this is best title for my question, if there is better, please suggest.

This is sample of working code, that is approximation of my real code, but it is fine for demonstration.

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);
}

Basically I have vectors of strings and I need to make N(already 2, but there will be more, around 20) vectors that need to have access to Strings from original vector.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

One solution that I have is to use to_owned(). And if I understand it correctly this is basically creating copy of String, so I end up with 2 same Strings in memory, which I find unnecessary wasted and would like to avoid it.

What is best way in Rust to do it ?

One solution that I have found is to convert original data Vec to &str, but not sure if that is best/correct way to do it in Rust(I am still beginner in Rust).

>Solution :

Without any more context on why you need those vectors or what you want to do with them, I see two ways you can take.

  1. Use references

This approach stores the string once in the data variable and stores references to these strings in the other vectors.

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. Use reference-counting smart pointers

This approach stores the strings on the heap, and uses the Arc type from the standard library which ensures via reference counting that the string on the heap will be deleted once all vectors have been deleted. The clone operation is cheap, it only increases the reference count.

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);
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading