impl Trait

Если ваша функция возвращает тип, реализующий MyTrait, вы можете записать возвращаемый тип как -> impl MyTrait. Это может достаточно сильно упростить сигнатуру вашей функции!

use std::iter;

use std::vec::IntoIter;

// Эта функция объединяет два `Vec` и возвращает итератор.

// Посмотрите какой получается сложный тип возвращаемого значения!

fn combine_vecs_explicit_return_type(

v: Vec,

u: Vec,

) -> iter::Cycle, IntoIter>> {

v.into_iter().chain(u.into_iter()).cycle()

}

// Это та же самая функция, но в возвращаемом типе использует нотацию `impl Trait`.

// Посмотрите как он упростился!

fn combine_vecs(

v: Vec,

u: Vec,

) -> impl Iterator {

v.into_iter().chain(u.into_iter()).cycle()

}

fn main() {

let v1 = vec![1, 2, 3];

let v2 = vec![4, 5];

let mut v3 = combine_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!("готово");

}

הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Что более важно, некоторые типы в Rust не могут быть записаны. Например, каждое замыкание имеет свой собственный безымянный тип. До появления синтаксиса impl Trait, чтобы вернуть замыкание, вы должны были аллоцировать её в куче. Но теперь вы можете сделать это всё статически, например так:

// Вернём функцию, которая добавляет `y` ко входному значению

fn make_adder_function(y: i32) -> impl Fn(i32) -> i32 {

let closure = move |x: i32| { x + y };

closure

}

fn main() {

let plus_one = make_adder_function(1);

assert_eq!(plus_one(2), 3);

}

הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Вы также можете использовать impl Trait для возврата итератора, который использует замыкания map или filter! Это упрощает использование map и filter. Из-за того, что замыкание не имеет имени, вы не можете явно записать возвращаемый тип для функции, возвращающей итератор с замыканием. Но с impl Trait вы можете сделать это:

fn double_positives<'a>(numbers: &'a Vec) -> impl Iterator + 'a {

numbers

.iter()

.filter(|x| x > &&0)

.map(|x| x * 2)

}

הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Загрузка...