• BatmanAoD@programming.dev
    link
    fedilink
    arrow-up
    4
    ·
    edit-2
    8 months ago

    The thing about Rust’s type inference that seems wild to anyone who hasn’t seen Hindley-Milner/ML style type systems before is that it’s “bidirectional” (in quotes because that’s not a proper type theory term as far as I know). The type of the left-side of an assignment can determine the type (and behavior!) of the right side. For instance, this is ambiguous:

    let foo = [("a", 1), ("b", 2)].into_iter().collect();
    

    The expression creates an iterator over the (letter, number) pairs, and collect() stores the elements in a newly created container. But which container type? Here are two valid variants:

    let foo: Vec<_> = [("a", 1), ("b", 2)].into_iter().collect();
    

    This creates a vector with items ("a", 1) and ("b", 2).

    let foo: HashMap<_, _> = [("a", 1), ("b", 2)].into_iter().collect();
    

    This creates a mapping where "a" and "b" are keys, and 1 and 2 are the corresponding values.

    Playground link in case you’d like to mess with this concept: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=76f999f4db600415643b0c58c19c69b7