Inferência de Tipo

Rust verá como a variável é usada para determinar o tipo:

fn takes_u32(x: u32) {
    println!("u32: {x}");
}

fn takes_i8(y: i8) {
    println!("i8: {y}");
}

fn main() {
    let x = 10;
    let y = 20;

    takes_u32(x);
    takes_i8(y);
    // recebe_u32(y);
}

Este slide demonstra como o compilador Rust infere tipos com base em restrições dadas por declarações e usos de variáveis.

É muito importante enfatizar que variáveis declaradas assim não são de um tipo dinâmico “qualquer tipo” que possa armazenar quaisquer dados. O código de máquina gerado por tal declaração é idêntico à declaração explícita de um tipo. O compilador faz o trabalho para nós e nos ajuda a escrever um código mais conciso.

O código a seguir informa ao compilador para copiar para um determinado contêiner genérico sem que o código especifique explicitamente o tipo contido, usando _ como placeholder:

fn main() {
    let mut v = Vec::new();
    v.push((10, false));
    v.push((20, true));
    println!("v: {v:?}");

    let vv = v.iter().collect::<std::collections::HashSet<_>>();
    println!("vv: {vv:?}");
}

collect depende de FromIterator, que HashSet implementa.