This confused me a lot when I started learning Rust. “Colon colon angle bracket” is what I searched for first because I had no idea the syntax had a name. It does: turbofish.
What does ::<T> tell the Rust compiler?
Think about what parse knows before the result has a concrete type.
Reveal the answer
It supplies a concrete generic type when Rust cannot infer one from the surrounding code.
Where I hit it
I had a string containing pi and wanted to parse it into a number:
fn main() {
let pi_string = "3.1415";
let pi_float = pi_string.parse().unwrap();
println!("{}", pi_float);
}It looks reasonable, but parse can produce many different types. At this point Rust has no way to know whether I want an f32, an f64, or something else.
error[E0284]: type annotations needed
--> src/main.rs:3:9
|
3 | let pi_float = pi_string.parse().unwrap();
| ^^^^^^^^ consider giving `pi_float` a type
What the compiler is asking for
The call to parse is generic. I need to provide the missing concrete type either on the function call or on the variable receiving the result.
Fix it with the turbofish
The ::<f32> after parse gives the compiler the type directly:
fn main() {
let pi_string = "3.1415";
let pi_float = pi_string.parse::<f32>().unwrap();
println!("{}", pi_float);
}3.1415
Or use a type annotation
The same information can come from the variable:
fn main() {
let pi_string = "3.1415";
let pi_float: f32 = pi_string.parse().unwrap();
println!("{}", pi_float);
}Both versions compile. I tend to use the form that makes the type easiest to see where I am reading the code.
What I keep in my head
::<T> fills in a generic type explicitly. With parse::<f32>(), the f32 is the concrete type that Rust could not infer on its own.