Exploring Rust - Part I: The Turbofish Syntax and Type Inference
Now I'm currently learning Rust, the approach I'm following is to use whatever code I see from the lessons I watch or read, then try to grok its syntax. One piece of code I tried to dissect is this one about vectors:
fn main() {
let mut words: Vec<String> = Vec::new();
}
Focusing on the first line after the function declaration, the part where a new vector was initialized, made me ask this question: "why is <String>
not declared on the Vec::new()
part, like Vec<String>::new()
"? Will it hurt if I also declare <String>
on the initialization part, just to keep things uniform?
Acting on that idea, I rewrote my code to this:
fn main() {
let mut words: Vec<String> = Vec<String>::new();
}
Then I re-compiled my code, but the Rust compiler rejected it and returned the following messages:
- error: comparison operators cannot be chained
- help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
I fixed my code by following the second message, with it being more useful as it's a direct solution to the problem. Why should it be written that way though?
Honestly, at this stage, I don't know yet. But here are my takeaways:
- The creators intended it to be that way. Just follow the "turbofish" syntax:
::<>
. It looks like a fish right? - Trust the compiler that it will do its work. Let it do type inference for you. This also saves you a few keystrokes.
Working code
fn main() {
// The commented code works fine, but for the sake of
// brevity, just infer the type of the vector.
//let mut words: Vec<String> = Vec::<String>::new();
let mut words: Vec<String> = Vec::new();
words.push(String::from("Foo"));
println!("words: {:?}", words);
}