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:?}"); }
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: () = ..
, щоб побачити повідомлення про помилку.