impl Trait

Подібно до меж трейтів, синтаксис impl Trait можна використовувати в аргументах функції та значеннях, що повертаються:

// Синтаксичний цукор для:
//   fn add_42_millions<T: Into<i32>>(x: T) -> i32 {
fn add_42_millions(x: impl Into<i32>) -> i32 {
    x.into() + 42_000_000
}

fn pair_of(x: u32) -> impl std::fmt::Debug {
    (x + 1, x - 1)
}

fn main() {
    let many = add_42_millions(42_i8);
    println!("{many}");
    let many_more = add_42_millions(10_000_000);
    println!("{many_more}");
    let debuggable = pair_of(27);
    println!("debuggable: {debuggable:?}");
}
This slide should take about 5 minutes.

impl Trait дозволяє працювати з типами, які ви не можете назвати. Значення impl Trait дещо відрізняється у різних позиціях.

  • У випадку параметра, impl Trait - це як анонімний загальний параметрp з обмеженням трейту.

  • Для типу, що повертається, це означає, що тип, що повертається, є деяким конкретним типом, який реалізує трейт, без назви типу. Це може бути корисно, коли ви не хочете викривати конкретний тип у публічному API.

    У позиції повернення виведення є складним. Функція, що повертає impl Foo, вибирає конкретний тип, який вона повертає, не записуючи його у вихідному коді. Функція, що повертає узагальнений тип, наприклад, collect<B>() -> B, може повернути будь-який тип, що задовольняє B, і користувачеві може знадобитися вибрати один з них, наприклад, за допомогою let x: Vec<_> = foo.collect() або turbofish, foo.collect::<Vec<_>>().

Який тип debuggable? Спробуйте let debuggable: () = .., щоб побачити повідомлення про помилку.