rust
测试驱动开发的思想
- 编写失败测试
- 编写使测试成功的代码
- 重构之前的代码
- 重复以上步骤
环境变量
可以通过std::env::var函数获取环境变量,该函数的返回结果为Result类型,可以通过is_ok方法来判断环境变量是否被设置。当环境变量被设置时,is_ok方法返回true,否则返回false。
示例:
代码语言:rust复制let tem = std::env::var("TEST").is_ok();
标准错误输出
可以使用eprintln!宏将错误信息输出到标准错误中,避免标准输出与标准错误的内容相混淆。
闭包
闭包定义
闭包是函数式编程中的基础概念,简要概括为,闭包是和上下文有关的函数,能够捕获其所在作用域中的变量。
在rust中,闭包为一个可以保存在变量中或作为参数传递的匿名函数。
闭包与类型注解
不同与普通函数,编译器可以通过编译器推断参数及返回值类型,因此可以不标明参数及返回值类型(也可自己加上类型声明)。
但是,如果多次调用同一个闭包,且参数类型,返回值类型不同,则编译器将会报错。(不同于python或js中的闭包)。
示例:
代码语言:rust复制// 普通函数
fn add_one_v1 (x:u32) -> u32 { x 1 }
//带类型注解的闭包
let add_one_v2 = |x: u32 | -> uu323 { x 1 };
//带花括号的闭包
let add_one_v3 = |x| { x 1 };
//最简写法的闭包
let add_one_v4 = |x| x 1 ;
闭包捕获环境的三种方式
- 捕获不可变借用
即不对捕获到的变量进行修改,仅对其进行读取操作
- 捕获可变借用
即对捕获到的变量进行修改,但不改变所有权
值得注意的是,可变借用与其他借用不能同时存在,因此闭包定义与调用之间的作用域中不能有其他不可变借用,如,不能在闭包定义与调用之间的作用域出现捕获到的变量的输出语句。
- 捕获所有权
即对捕获到的变量的所有权进行更改
可以通过move关键字强制捕获变量的所有权,在使用线程时,这点尤其重要。因为若只捕获不可变借用,主线程可能在新线程运行前将该变量丢弃,导致线程的不可变引用失效。
闭包、闭包体
闭包能够捕获其环境中的变量的引用或所有权(影响什么移进闭包,如有),闭包体(函数体)中的代码定义了对引用或值进行的操作(影响什么移出闭包,如有)。
闭包体能够进行三种操作:
- 将一个捕获的值移出闭包
更改所有权或引用
- 修改捕获到的值
修改具有可变引用或所有权的值
- 不从环境中捕获值或不移动也不修改捕获到的值
仅捕获不可变引用或压根不需要捕获变量
Fn trait
闭包自动、渐进地实现一个或多个Fn trait,无需显式声明,也可自行定义闭包实现的Fn trait
Fn trait有三种:
- FnOnce 适用于能调用一次的闭包,所有闭包都至少实现了FnOnce Trait,因为所有闭包都能至少调用一次
- FnMut 适用于不会将捕获到的值移出闭包体的闭包,但可能会修改捕获到的值
- Fn 适用于既不将捕获到的值移出闭包体,又不修改捕获到的值的闭包 ,也包括不从环境中捕获值的闭包,这类闭包在并发调用的场景中十分重要