Rust迭代器和闭包


在本章中,我们将学习RUST中迭代器和闭包的工作方式。

迭代器


迭代器用于迭代值的集合,例如数组、向量、映射等。

迭代器实现Rust标准库中定义的Iterator trait,iter()方法返回集合的迭代器对象,迭代器对象中的值称为项目,next() 方法可用于遍历项目, 当next()方法到达集合的末尾时,该方法将返回值None。

下面的示例使用迭代器从数组中读取值。

fn main() {
    //声明一个数组
    let a = [10,20,30];

    let mut iter = a.iter();
    //获取数组的迭代器对象
    println!("{:?}",iter);

    //从迭代器对象获取单个值
    println!("{:?}",iter.next());
    println!("{:?}",iter.next());
    println!("{:?}",iter.next());
    println!("{:?}",iter.next());
}
Iter([10, 20, 30])
Some(10)
Some(20)
Some(30)
None

像数组或向量这样的集合实现了Iterator trait,则可以使用for ... in语法遍历它,如下所示:

fn main() {
    let a = [10,20,30];
    let iter = a.iter();
    for data in iter{
        print!("{}\t",data);
    }
}
10 20 30

以下3种方法从集合中返回迭代器对象,其中T表示集合中的元素。

序号
方法与说明
1

iter()

给出&T的迭代器(对T的引用)

2

into_iter()

给出T上的迭代器

3

iter_mut()

给出&mut T的迭代器

例子:iter()

iter()函数使用了借用的概念,它返回集合中每个元素的引用,遍历时使集合保持不变,并在循环后可以重用。

fn main() {
    let names = vec!["Kannan", "Mohtashim", "Kiran"];
    for name in names.iter() {
        match name {
            &"Mohtashim" => println!("There is a rustacean among us!"),
            _ => println!("Hello {}", name),
        }
    }
    println!("{:?}",names);
    //迭代后重用集合
}
Hello Kannan
There is a rustacean among us!
Hello Kiran
["Kannan", "Mohtashim", "Kiran"]

例子:into_iter()

此函数使用所有权的概念,它将集合中的值移动到一个iter对象中,即该集合已被使用,并且不再可供重用。

fn main(){
    let names = vec!["Kannan", "Mohtashim", "Kiran"];
    for name in names.into_iter() {
        match name {
            "Mohtashim" => println!("There is a rustacean among us!"),
            _ => println!("Hello {}", name),
        }
    }
    //迭代后无法重用集合
    // println!(“ {:?}”,names);
    //错误:所有权移动后无法访问
}
Hello Kannan
There is a rustacean among us!
Hello Kiran

例子:for和iter_mut()

这个函数类似iter()函数,但是此函数可以修改集合中的元素。

fn main() {
    let mut names = vec!["Kannan", "Mohtashim", "Kiran"];
    for name in names.iter_mut() {
        match name {
            &mut "Mohtashim" => println!("There is a rustacean among us!"),
            _ => println!("Hello {}", name),
        }
    }
    println!("{:?}",names);
    //迭代后重用集合
}
Hello Kannan
There is a rustacean among us!
Hello Kiran
["Kannan", "Mohtashim", "Kiran"]

闭包(Closure)


闭包是指在一个函数内定义另外一个匿名函数,闭包可用于将函数分配给变量,这允许程序将函数作为参数传递给其他函数,闭包也称为内联函数,内联函数可以访问外部函数中的变量。

语法:定义闭包

闭包定义可以可选地具有参数。参数包含在两个垂直条中。

let closure_function = |parameter| {
    //逻辑
}

调用Closure实现的语法Fn特质。因此,可以使用()语法。

closure_function(parameter);    //调用

例子

以下示例在main()函数内定义了一个闭包is_even。如果数字为偶数,则闭包返回true;如果数字为奇数,则闭包返回false。

fn main(){
    let is_even = |x| {
        x%2==0
    };
    let no = 13;
    println!("{} is even ? {}",no,is_even(no));
}
13 is even ? false

例子

fn main(){
    let val = 10;
    //在外部声明
    let closure2 = |x| {
        x + val //内部函数访问外部fn变量
    };
    println!("{}",closure2(2));
}

main()函数声明一个变量val和闭包,闭包访问外部函数main()中声明的变量。

12