I am trying to learn Rust, and am trying to write a simple program that takes arguments from the command line, to get used to some basic concepts. The code I wrote to handle the arguments, fails, and I feel like I am missing some basic concept.
fn process_args(args: Vec<String>) {
let my_string: String = String::from("--verbose");
for item in &args[1..] {
match item{
my_string=>do_something_with_argument(),
_=>println!("unexpected argument {item}"),
}
}
}
Where vscode tells me that the ‘my_string’, variable is unused.
I also tried this version:
fn process_args(args: Vec<String>) {
for item in &args[1..] {
match item{
"--verbose"=>do_something_with_argument(),
_=>println!("unexpected argument {item}"),
}
}
}
which fails because the string literal cannot be matched with a string, then I tried:
fn process_args(args: Vec<String>) {
for item in &args[1..] {
match item{
String::from("--verbose")=>do_something_with_argument(),
_=>println!("unexpected argument {item}"),
}
}
}
Which also does not work.
What am I missing. I feel like they all should work.
>Solution :
The left hand side of a "match" arm is a pattern. If you have a name in a pattern, it’s an implicit declaration. So in the first version, the first arm is just a pattern for any value, binding it to the (new) local variable my_string. Some languages (e.g. erlang) can dereference variables in patterns, Rust can’t.
The third version can not work, because a function call is not a valid pattern.
The second version actually nearly works if you bother to read the compiler error:
error[E0308]: mismatched types
--> src/lib.rs:4:13
|
3 | match item {
| ---- this expression has type `&String`
4 | "--verbose" => {},
| ^^^^^^^^^^^ expected `&String`, found `&str`
|
= note: expected reference `&String`
found reference `&'static str`
item is an &String, but the pattern only matches &str, so all you need to do is make the two match by "converting" item to an &str, via String::as_str or &** for instance:
fn process_args2(args: Vec<String>) {
for item in &args[1..] {
match &**item {
"--verbose" => {},
_=>println!("unexpected argument {item}"),
}
}
}
Although I would also say that this is not very useful, you’re testing flags for equality, why don’t you just… test flags for equality? Using ==? It’s not like Rust can construct a jump table from strings.