CodeBlanks Logo Icon CodeBlanks

Turbofish

Help type inference with the ::<> turbofish.

Turbofish

When the compiler can't infer a generic type from context, the type is given after the function or method name with ::<T>. This syntax is called the "turbofish":

let n = "42".parse::<i32>().unwrap();
let v = (1..4).collect::<Vec<i32>>();
let t = [1, 2, 3].iter().sum::<i32>();
let bos = Vec::<String>::new();

The same information can be given by annotating the variable: let n: i32 = "42".parse().unwrap();. In the middle of a chain there's no variable, so the turbofish is needed.

Why is it needed?

parse and collect behave differently depending on the return type: parse can produce i32, f64, bool or IpAddr; collect can produce a Vec, String, HashSet or HashMap. The compiler can't generate code without knowing which you want:

let harfler = "abc".chars().collect::<String>();   // "abc"
let kume = [3, 1, 3].into_iter().collect::<std::collections::HashSet<_>>();
println!("{harfler} {}", kume.len());   // abc 2

Practice Extract numbers

Split the text let s = "1 2 3 4"; at spaces, convert each piece with parse::<i32>() and collect with collect::<Vec<_>>(). Compute the sum with sum::<i32>(); print the vector and the sum separated by a space.

Starter code

main.rs
fn main() {
    // buraya yaz
}

Sample solution

main.rs
fn main() {
    let s = "1 2 3 4";
    let v = s.split(' ').map(|x| x.parse::<i32>().unwrap()).collect::<Vec<_>>();
    let t = v.iter().sum::<i32>();
    println!("{:?} {}", v, t);
}

Expected output

[1, 2, 3, 4] 10

Questions and answers

Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.

1 What does the <code>_</code> in <code>collect::&lt;Vec&lt;_&gt;&gt;()</code> mean?

  • An unused value
  • Let the compiler infer the element type Correct answer
  • An empty vector
  • Any type is accepted

Explanation: You choose the container type (Vec); the compiler infers the element type from the iterator.

2 Give the target type

Question
let n = "42".parse____().unwrap();
Answer
let n = "42".parse::<i32>().unwrap();

Explanation: ::<T> is written after the method name.

3 Expression and result

Term Meaning
"7".parse::<u8>() Ok(7)
"ab".chars().collect::<String>() "ab"
[1, 2].iter().sum::<i32>() 3
Vec::<i32>::new().len() 0

All lessons in Intermediate