如何在一个所有权为owned的Vec中复制或借用一个已拥有的String引用?

11

我试图先将一个字符串设置为默认值,但如果给出命令行参数,则更新该字符串...

这是我的起点(无法编译):

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

所以,(我认为)env::args() 给了我一个拥有向量或拥有字符串... 我应该如何做到以下两点之一:

  • 复制向量中的字符串
  • 获取向量中字符串的引用

注意:

$ rustc --version
rustc 1.8.0 (db2939409 2016-04-11)
1个回答

16
在 Rust 中,要创建一个元素的副本,它应该实现 Clone 特性,并因此拥有 .clone() 方法。 String 实现了 Clone,所以:
config_file = args[1].clone();

然而,你的方法存在许多不必要的内存分配;我们可以做得更好。没有必要创建一个Vecargs()产生一个迭代器,因此让我们直接使用它并挑选有趣的值。

考虑到这一点:

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

应 Shepmaster 之邀,现在开始表演!

下面是一个等价的程序,没有可变性或转义字符,并且尽量少分配内存:

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

它在nth(1)返回的Option上使用unwrap_or_else,以获取Option的内容或(如果没有内容),使用传递的lambda生成值。

它还展示了原始字符串字面量,这是一个很棒的功能,在需要嵌入反斜杠的字符串中使用。


2
非常好,感谢您回答问题并提供进一步的改进 :thumbsup: - Gavin Hope
1
所有那些不必要的可变性、分配和转义字符!你可以将其精简一些。^_^ - Shepmaster

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