闭包定义 声明 使用 | 1.闭包是什么 1.闭包允许在其定义的作用域之外访问变量 2.闭包如何声明 let a = | 传递给闭包的参数 | -> 闭包返回的类型 { 闭包的实现 } 3.如何调用闭包 像调用函数一样被调用 let result = 函数名(参数1,参数2) 4.闭包可以使用闭包外的环境变量 let x = 5; let square = |num| num * x println !("{}",square(3)) //输出15 5.获取所有权:获取到外部变量的使用权后,闭包可以访问该变量,外部不能访问 let s = String::from("hello") let print_s = move || println !("{}",s ) //move:获取变量的所有权 而不是借用它们 print_s() //prilntln !("{}",s ) //这行代码会报错,因为s的所有权已经转到了闭包 |
闭包作为参数 | 6.闭包如何作为参数 1.定义了函数,它可以接收一个泛型参数,这个泛型参数可以是任何类型 2.但不能使用这个参数,因为它还不是一个具体类型 3.需要给泛型 取一个名字 比如F 4.rust编译器不知道F是什么类型,它需要一些帮助来解释F是什么 这就是泛型约束 fn call_fn<F>(f: F) where F: Fn() { //<F>:泛型参数的声明 where F:Fn() F必须实现Fn() trait f();F } |
闭包和错误处理 | 7.闭包和错误处理 1.错误处理 fn divide(a: i32, b: i32) -> Result<i32, String> { if b == 0 { return Err("Divisionby zero".to_string()); } Ok(a / b) } 2.闭包的错误处理 .filter(|x| x % 2 === 0 ) .collect::<Result<Vec<_>,String>>()? 解释 .collect::<Result<Vec<_>,String>>() .collect:Vec类型的一个方法,将迭代器中的元素收集到一个向量中 ::作用域解析运算符 访问结构体 枚举 模块 和关联函数的成员 <> 指定泛型参数的类型约束 Result<> result类型,包含两个参数 Vec:可变动态数组 <_>: 定义泛型类型的参数 _:类型参数占位符 |
闭包和多线程 | 8.闭包和多线程 1.在不同线程中使用共享数据和执行任务 如何在多线程中使用闭包 1.使用move关键字 fn main(){ let s = String::from("hello") let handle = thread::spawn(move || { println!("{}",s); }) handle.join().unwrap(); } |
闭包和生命周期 | 生命周期:生命周期用于确保引用始终有效 1.借用环境中的变量 let x = 5; let print_x = || println!("x: {}",x); print_x(); 2.可变借用环境中的变量 let mut y = 10; let mut add_to_y = || y+=1 add_to_y(); println!("y:{}",y); 3.所有权转移 let z = String::from("hello") let move_z = move || println!("z:{}",z); move_z(); |
闭包的类型 | 1.Fn:表示闭包可以多次被调用 每次调用都会借用环境中的变量 2.FnMut:闭包可以多次被调用 但每次可变地借用环境中地变量 3.FnOnce:闭包只能被调用一次 因为调用时会消耗环境中的变量。这些变量的所有权会被移动到闭包中,因此在闭包外部不能再使用这些变量 |