8
\$\begingroup\$

I'm just starting out in Rust and I find the concept of ownership confusing so I wrote an implementation of the echo command. I would like to know if I could have set the initial value on the echo variable any better or just any general improvements.

use std::env;

fn main() {
    let args: Vec<String> = env::args().collect();

    let mut echo: String;
    if let Some(string) = args.get(1) {
        echo = string.to_string();
    } else {
        return;
    }

    for arg in &args[2..] {
        echo.push(' ');
        echo.push_str(arg.as_str());
    }
    echo.push('\n');

    println!("{}", echo);
}
\$\endgroup\$
2
  • 2
    \$\begingroup\$ Actually this answer cover almost all I could say. \$\endgroup\$
    – Stargateur
    Sep 12, 2018 at 17:46
  • \$\begingroup\$ @Stargateur Thanks a lot! I forgot to mention I didn't want to use any external crates so that works really well for me. \$\endgroup\$ Sep 12, 2018 at 17:55

2 Answers 2

6
\$\begingroup\$

I would not say I am any more proficient but I would make these changes if I wrote it.

  • skip(1) first arg.
  • join(" ") instead of iterate though args.

You do not need a mutable value.

use std::env;

fn main() {
    let args: Vec<String> = env::args().skip(1).collect();

    if args.len() == 0 {
        println!("");
    } else {
        println!("{}", args.join(" "));
    }
}

I would do one more thing and send to stdout since your mimicking echo, but maybe much for this answer.

\$\endgroup\$
4
  • \$\begingroup\$ I didn't realize env::Args implemented the Iterator trait. It's definitely more elegant than my code, thanks! \$\endgroup\$ Sep 13, 2018 at 3:22
  • \$\begingroup\$ Thank you. Honestly there are more cool tricks, I think you can get away with just join no 'if'. \$\endgroup\$ Sep 13, 2018 at 7:45
  • \$\begingroup\$ @Genuinebyte I didn't realize env::Args implemented the Iterator trait. — where did you think collect was coming from? \$\endgroup\$
    – Shepmaster
    Sep 14, 2018 at 0:27
  • \$\begingroup\$ What if you just omitted the if args.len() == 0 branch completely? That would make the code even shorter. \$\endgroup\$ Oct 16, 2019 at 1:00
6
\$\begingroup\$
  1. Use Iterator::skip instead of collecting the arguments into a Vec and then skipping over it.

  2. This implementation should not have any allocation, whatsoever. Neither collecting the arguments or building an output string is needed.

use std::env;

fn main() {
    let mut args = env::args().skip(1);

    if let Some(arg) = args.next() {
        print!("{}", arg);

        for arg in args {
            print!(" {}", arg);
        }
    }

    println!();
}
\$\endgroup\$
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.