Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to copy or borrow a reference to, an owned String inside an owned Vec?

Tags:

rust

I'm trying to first set a String to be some default, but then update that String if a command line argument has been given...

This is my starting point (which doesn't compile):

use std::env;

fn main() {
    let mut config_file = "C:\\temp\\rust\\config.txt".to_string();
    let args: Vec<String> = env::args().collect();
    if args.len() > 1 {
        config_file = args[1];
    }
    println!("Config file path: {}", config_file);
}

So, (I think) env::args() is giving me an owned vector or owned strings... How do I either:

  • Copy a string in the vector
  • Get a reference to a string in the vector

Note:

$ rustc --version
rustc 1.8.0 (db2939409 2016-04-11)
like image 340
Gavin Hope Avatar asked Aug 03 '16 15:08

Gavin Hope


1 Answers

In Rust, to create a copy of an element, it should implement the Clone trait, and thus have a .clone() method.

String implements Clone, thus:

config_file = args[1].clone();

Your method, however, has many unnecessary memory allocations; we can do better there is no need to create a Vec, args() yields an iterator so let's use that directly and cherry-pick the interesting value.

With this in mind:

fn main() {
    let mut config_file = "C:\\temp\\rust\\config.txt".to_string();

    if let Some(v) = env::args().nth(1) {
        config_file = v;
    }

    println!("Config file path: {}", config_file);
}

At the behest of Shepmaster: it's show time!

The following is an equivalent program, without mutability or escape characters, and with as little allocations as possible:

fn main() {
    let config_file = env::args()
        .nth(1)
        .unwrap_or_else(|| r#"C:\temp\rust\config.txt"#.to_string());

    println!("Config file path: {}", config_file);
}

It uses unwrap_or_else on the Option returned by nth(1) to get either the content of the Option or, if none, generate a value using the passed lambda.

It also show cases the Raw String Literals, a great feature to use when having to embed back slashes in a string.

like image 86
Matthieu M. Avatar answered Dec 07 '22 16:12

Matthieu M.