当前位置:网站首页>Rust language -- iterators and closures

Rust language -- iterators and closures

2022-07-06 02:44:00 A pig

  • Closure

Anonymous functions that can capture their environment , Closure is a function , The definition of this function can be assigned to a variable

Example — Program for generating custom exercise plan

The goal is : Don't let users wait unnecessarily

fn main(){
    // Create closures 
    let expensive_closure = |num1, num2|{
        num1+num2
    };
    let b = expensive_closure(11, 12);// Call closure 
    println!("{}", b);//23
}

Closures do not require annotation of the types of parameters and return values , It can be inferred by itself , Of course, you can also manually mark

fn main(){
    let expensive_closure = |num1, num2|{
        num1+num2
    };
    let b = expensive_closure(11, 12);// The first call has determined the parameters and return value types of the closure , And it can't be changed 
    let c = expensive_closure(11.0, 12.0);// Report errors , Because it has been inferred i32, i32
}

To avoid executing a time-consuming function many times, we can use closures and cooperate struct,struct Hold the closure and its call result

struct Cacher<T>
    where T:Fn(u32)->u32
    {
        calculation:T,
        value:Option<u32>,
    }
impl<T> Cacher<T>
where T:Fn(u32)->u32{//Fn(u32)->u32  Is a closure type 
    fn new(calculation:T)->Cacher<T>{
        Cacher{
            calculation,
            value:None,
        }
    }
    fn value(&mut self, arg:u32)->u32{
        match self.value{
            Some(v)=>v,
            None=>{
                let v = (self.calculation)(arg);
                self.value = Some(v);
                v
            },
        }
    }
}

Closures can capture variables in the same environment as closures , Function can't

move Keyword can force a closure to take ownership of the environment value it uses

fn main(){
    let a = 2;
    let test1 = |number|{number};
    let b = test1(a);// Successfully captured environment variables a
    println!("{}", a);// here a The ownership of is not taken away by closures 
}
fn main(){
    let x = vec![1, 2, 3];
    let equal_to_x = move |z| z==x;
    println!("{:#?}", x);//move Take ownership of environment variables 
    let y = vec![1, 2, 3];
    assert!(equal_to_x(y))
}
  • iterator

  Traverse each element : .iter()

iterator trait Only one method is required :next

next: Go down one item at a time

One item of the iterator is returned each time

The returned results are wrapped in Some in

End of the iteration , return None

You can call directly on the iterator next Method

fn main(){
    let vec = vec![1, 2, 3];
    let mut v1_iter = vec.iter();
    assert_eq!(v1_iter.next(), Some(&1));
    assert_eq!(v1_iter.next(), Some(&2));
    assert_eq!(v1_iter.next(), Some(&3));
    assert_eq!(v1_iter.next(), None);
}

sum() function

fn main(){
    let vec = vec![1, 2, 3];
    let v1_iter = vec.iter();
    let total:i32 = v1_iter.sum();
    println!("sum = {}", total);//6
}

map() Method to change an iterator into another iterator

fn main(){
    let vec = vec![1, 2, 3];
    let v1_iter = vec.iter();
    
    let iter_map:Vec<_> = v1_iter.map(|x|x+1).collect(); 
    println!("{:#?}", iter_map);//2, 3, 4
}

filter Method :

Receive a closure , This closure traverses each element of the iterator , return bool type

If the closure returns true: The current element will be contained in filter In the generated iterator , if false Will not be included in filter In the generated iterator

原网站

版权声明
本文为[A pig]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/02/202202140000372693.html