Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

The Placeholder Type _

Goal of This Episode

Learn to use _ in type annotations to let the compiler infer part of a type.

Concept

Last episode’s turbofish specifies all the type parameters by hand. But sometimes you only want to specify some of them and let Rust infer the rest. That’s when _ serves as a type-level wildcard.

_ as a Type Placeholder

Take this example:

fn main() {
    let v: Vec<_> = vec![1, 2, 3];
}

We’re telling Rust “this is a Vec,” while the element type _ says “you figure it out.” Rust sees 1, 2, 3 are integers and infers _ = i32.

_ works inside a turbofish too:

fn main() {
    let v = Vec::<_>::new();
}

Though written this way it’s really no different from Vec::new() with full inference. _ shines when you need to specify the outer type but let Rust infer the inner one.

When Is It Useful?

When a type has several parameters and you only want to annotate some. The power of _ grows with the type’s complexity — you’ll feel it naturally once we meet more standard-library types.

Example Code

fn main() {
    // Let Rust infer the Vec's element type with _
    let v: Vec<_> = vec![1, 2, 3];
    println!("{:?}", v);

    // _ works in a turbofish too
    let v2 = Vec::<_>::new(); // Same as Vec::new(); _ lets Rust infer
    let v2: Vec<i32> = v2;    // The type is inferred from later usage
    println!("{:?}", v2);

    // Comparison: no annotation at all vs partial annotation with _
    let a = vec![true, false]; // Rust infers everything: Vec<bool>
    let b: Vec<_> = vec![true, false]; // Tell Rust it's a Vec; element type inferred
    println!("{:?}", a);
    println!("{:?}", b);
}

Recap

  • _ can stand in as a placeholder in type annotations, letting Rust infer that position’s type.
  • Good for “I know the outer type; let Rust infer the inner one.”
  • Both turbofish and let annotations can use _.