impl Trait

Si tu función devuelve un tipo que implementa MiRasgo, puedes escribir el tipo que devuelve como -> impl MiRasgo. ¡Esto puede ayudar a simplificar bastante las signaturas de tipo!

use std::iter;
use std::vec::IntoIter;

// Esta función combina dos `Vec<i32>` y devuelve un iterador sobre él.
// ¡Mira lo complicado que es su tipo que devuelve!
fn combina_vecs_tipo_explicito(
    v: Vec<i32>,
    u: Vec<i32>,
) -> iter::Cycle<iter::Chain<IntoIter<i32>, IntoIter<i32>>> {
    v.into_iter().chain(u.into_iter()).cycle()
}

// Esta es exactamente la misma función, pero el tipo que devuelve usa `impl Trait`.
// ¡Mira lo sencillo que es!
fn combina_vecs(
    v: Vec<i32>,
    u: Vec<i32>,
) -> impl Iterator<Item=i32> {
    v.into_iter().chain(u.into_iter()).cycle()
}

fn main() {
    let v1 = vec![1, 2, 3];
    let v2 = vec![4, 5];
    let mut v3 = combina_vecs(v1, v2);
    assert_eq!(Some(1), v3.next());
    assert_eq!(Some(2), v3.next());
    assert_eq!(Some(3), v3.next());
    assert_eq!(Some(4), v3.next());
    assert_eq!(Some(5), v3.next());
    println!("todo listo");
}

Más importante aún, algunos tipos de Rust no se pueden escribir. Por ejemplo, cada clausura tiene su propio tipo concreto sin nombre. Antes de la sintaxis de impl Trait, tenías que realizar una asignación en el montículo para devolver una clausura. Pero ahora puedes hacerlo todo de forma estática, así:

// Devuelve una función que agrega `y` a su entrada
fn hacer_una_funcion_sumadora(y: i32) -> impl Fn(i32) -> i32 {
    let clausura = move |x: i32| { x + y };
    clausura
}

fn main() {
    let mas_uno = hacer_una_funcion_sumadora(1);
    assert_eq!(mas_uno(2), 3);
}

¡También puedes usar impl Trait para devolver un iterador que usa clausuras map o filter! Esto facilita el uso de map y filter. Debido a que los tipos de clausura no tienen nombres, no puedes escribir un tipo de retorno explícito si su función devuelve iteradores con clausuras. Pero con impl Trait puedes hacer esto fácilmente:

fn dobles_positivos<'a>(numeros: &'a Vec<i32>) -> impl Iterator<Item = i32> + 'a {
    numeros
        .iter()
        .filter(|x| x > &&0)
        .map(|x| x * 2)
}