Rust开发——闭包使用示例

闭包

  1. 闭包是可以捕获所在环境的匿名函数。闭包的定义:|参数列表| -> 返回类型 {代码段}
    |x:u8| -> u8 
    {
    
    
        let y = x +1;
         y
    };
  1. 闭包是一个匿名函数。
    像下面合法定义,||是闭包的参数
	|| 45;
    |x:u8| x + 1;
    |x:u8| -> u8 {
    
     x + 1 };
  1. 闭包是把一个函数保存为变量,可以作为参数使用。
 let y = |x:u32| x+10;
 print!("{}\n",y(5))
  1. 可以在一个地方创建闭包,然后在另一个上下文中调用闭包来完成运算。
    在这里插入图片描述
 //如果只定义不调用,会报错
    let add = |a|{
    
    a+1};
    add(1);//推导出类型完成计算

如果有两次调用,则第二次推导失败

 //如果只定义不调用,会报错
    let add = |a|{
    
    a+1};
    add(1);
    add(2.0);
  • 闭包不要求标注参数和返回值的类型
  • 闭包通常很短小,只在狭小的上下文言中工作,编译器通常能推断出类型
  • 闭包可以手动添加类型标注
  1. 可以在定义的地方直接调用
let str = (|x:String|x + &" world".to_string())("hello".to_string());
print!("{}\n",str);
  1. 可以从其定义的作用域捕获值。
    let m = 5;
    let add = |a|{
    
    a+m};//这里捕获了当前环境外部m的值
    print!("{}\n",add(10));//输出15

闭包捕获变量关联的trait定义

pub trait FnOnce<Args> {
    
    
    type Output;
    fn call_once(self, args: Args) -> Self::Output;
}

pub trait FnMut<Args>: FnOnce<Args> {
    
    
    fn call_mut(&mut self, args: Args) -> Self::Output;
}

pub trait Fn<Args>: FnMut<Args> {
    
    
    fn call(&self, args: Args) -> Self::Output;
}
  • Fn:如果闭包只是对捕获变量不做修改操作,闭包捕获的是&T类型,闭包按照Fn trait方式执行,闭包可以重复多次执行。
  • FnMut:如果闭包对捕获变量有修改操作,闭包捕获的是&mut T类型,闭包按照FnMut trait方式执行,闭包可以重复多次执行
  • FnOnce:如果闭包会消耗掉捕获的变量,变量被move进闭包,闭包按照FnOnce trait方式执行,闭包只能执行一次

7.闭包作为函数参数传递

这样写是不可以的,因为闭包不属于任何类型,本质闭包是trait

fn main()
{
    
    
    let x = |y:u16| {
    
    y+10};
    add(x);
}

fn add(x : u16)
{
    
    
    x(10);
}

这两种写法都可以:

fn main()
{
    
    
    let x = |y|{
    
    print!("{} \n",y)};
    foo_1(x);
}

fn foo_1<F : Fn(u16)>(x: F) 
{
    
    
    x(5);
}

fn foo_2(x: impl Fn(u16))
{
    
    
    x(10);
}
  1. 返回闭包
    闭包属于trait,这意味着不能直接返回闭包。对于大部分需要返回trait的情况,可以使用实现了期望返回trait的具体类型来替代函数的返回值。但是这不能用于闭包,因为他们没有一个可返回的具体类型;例如不允许使用函数指针fn作为返回值类型。
    下面的例子编译不能通过
fn return_closure() -> Fn(i32) -> i32 
{
    
    
    |x| x+1
}

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/matt45m/article/details/126456195