Rust\'s str
class has a parse
method that returns a FromStr
object. parse
is templated, and so the type that\'s being parsed
It's just not clear what m is here, as there isn't enough information to say. Is it an i32? A u64? Nobody, including Rust, can know.
You need to do something to help figure out what type it is. Either pass it to a function expecting a specific type, or annotate it such that it can be determined what type it should be.
Rust's
str
class has aparse
method that returns aFromStr
object.
Stop right here, this is your error.
parse
does not return a FromStr
object; FromStr
is a trait
which can be thought of as an abstract class if you come from an OO background, and you cannot return an object with an abstract type: it's abstract!
What parse
does return, thus, is an instance of some type T
which must implement the FromStr
interface.
But failing to specify the type does not seem to be an error in itself. Instead, I get an error when trying to print the resulting (generic/unspecified)
FromStr
object
Because there cannot be such generic/unspecific FromStr
object. A concrete type must be inferred (from context) or explicitly spelled out, and this type must implement FromStr
.
So what is
m
here?
Only you know what it should be, the compiler does not, and thus complain that it does not know what to do :)
Or is the "unable to infer enough type information" error actually due to the fact that parse in fact can't be called without a type specifier, and the compiler just doesn't catch the error until the first line where the resulting
Ok
type is actually used?
Basically.
Except that it's not so much that the compiler doesn't catch the error until the first line where the resulting Ok
is used, and more that the compiler considers the full function at once when inferring types. From the point of view of the compiler, whether the actual clue to infer the type comes immediately or comes 50 lines down does not matter, it only needs to be present in the current function body.
It might lead to the complaint about the lack of type originating in an odd place from the developer point of view; this is one of the downfalls of type inference. On the other hand, the compiler just cannot know where YOU would prefer to put the annotation. There are after all many possibilities:
// Example 1: immediately specifying the type
fn main() {
let foo = "3".parse::<i32>();
match foo
{
Ok(m) => println!("foo: {}", m),
Err(e) => println!("error! {}", e)
}
}
// Example 2: partially specifying the result type
// Note: the "_" is deduced to be std::num::ParseIntError because
// this is how `FromStr::Err` is defined for `i32`.
fn main() {
let foo: Result<i32, _> = "3".parse();
match foo
{
Ok(m) => println!("foo: {}", m),
Err(e) => println!("error! {}", e)
}
}
// Example 3: specifying the result type of unwrapping
fn doit() -> Result<(), std::num::ParseIntError> {
let foo: i32 = try!("3".parse());
println!("foo: {}", foo);
Ok(())
}
fn main() {
match doit()
{
Ok(_) => (),
Err(e) => println!("error! {}", e)
}
}
// Example 4: letting the type be inferred from a function call
fn callit(f: i32) {
println!("f: {}", f);
}
fn main() {
let foo = "3".parse();
match foo
{
Ok(m) => callit(m),
Err(e) => println!("error! {}", e)
}
}