If you want to match against something then you need something to destructure on. You can match against string slices, but only a finite set, so that doesn't help here.
So let's have an enum to match on:
enum Value {
Int(isize),
Float(f64),
}
use Value::*; // Make the variants available without Value::
Then you need to parse the string into the appropriate type. You can use the parse method for each type (if you're happy with Rust's syntax for those; otherwise you might need a fancier parser):
fn parse_string(s: &str) -> Option<Value> {
if let Ok(i) = s.parse() { // inferred as isize from next line
Some(Int(i))
} else if let Ok(f) = s.parse() {
Some(Float(f))
} else {
None
}
}
Note that when trying parses in sequence like this the order matters; "123" would parse as an f64 too.
I'm turning any parse errors into None and using Option rather than Result because it's not clear what the error would be (since each parse can return its own); in a real application I might have a ParseError type.
Now we can match on the result:
fn main() {
let x = "123";
match parse_string(x) {
Some(Int(i)) => println!("int {}", i),
Some(Float(f)) => println!("float {}", f),
None => println!("Didn't parse"),
}
let x = "123.5";
match parse_string(x) {
Some(Int(i)) => println!("int {}", i),
Some(Float(f)) => println!("float {}", f),
None => println!("Didn't parse"),
}
}
Runnable playground link
Resultreturned fromread_line..expect("Could not read input")). For a one-off script, I agree that aborting is a reasonable way to handle the error, as opposed to something more user-friendly.unwrap()is trivial to write even in a one-off script, and it can save you serious pain in cases where the error would have otherwise gone undetected.expectoverunwrap, just so when the failure occurs it's much easier to find it.