How to push a value to a Vec and append it to a String at the same time?

我的梦境 提交于 2021-01-29 11:09:10

问题


I want to write a program that sets the shell for the system's nslookup command line program:

fn main() {
    let mut v: Vec<String> = Vec::new();
    let mut newstr = String::from("nslookup");
    for arg in std::env::args() {
        v.push(arg);
        newstr.push_str(&format!(" {}", arg));
    }
    println!("{:?}", v);
    println!("{}", newstr);
}
error[E0382]: borrow of moved value: `arg`
 --> src/main.rs:6:41
  |
5 |         v.push(arg);
  |                --- value moved here
6 |         newstr.push_str(&format!(" {}", arg));
  |                                         ^^^ value borrowed here after move
  |
  = note: move occurs because `arg` has type `std::string::String`, which does not implement the `Copy` trait

How to correct the code without traversing env::args() again?


回答1:


Reverse the order of the lines that use arg:

for arg in std::env::args() {
    //newstr.push_str(&format!(" {}", arg));
    write!(&mut newstr, " {}", arg);
    v.push(arg);
}

Vec::push takes its argument by value, which moves ownership of arg so it can't be used anymore after v.push(arg). format! and related macros implicitly borrow their arguments, so you can use arg again after using it in one of those.

If you really needed to move the same String to two different locations, you would need to add .clone(), which copies the string. But that's not necessary in this case.

Also note that format! creates a new String, which is wasteful when all you want is to add on to the end of an existing String. If you add use std::fmt::Write; to the top of your file, you can use write! instead (as shown above), which is more concise and may be more performant.

See also

  • What are move semantics in Rust?
  • error: use of moved value - should I use "&" or "mut" or something else?
  • Does println! borrow or own the variable?



回答2:


You can do like that:

fn main() {
    let args: Vec<_> = std::env::args().collect();
    let s = args.join(" ");

    println!("{}", s);
}

First, you create the vector, and then you create your string.



来源:https://stackoverflow.com/questions/54114915/how-to-push-a-value-to-a-vec-and-append-it-to-a-string-at-the-same-time

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!