学习rust_day08

生命周期

当引用的生命周期可能以几种不同的方式相关联时,就必须标注生命周期了。

借用检查器Borrow Checker

  • 确保数据存活的时间长于其引用(Outlive)
  • 比较作用域,以确定所有的借用是否有效

例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
//函数中的泛型生命周期
fn main() {
let string1 = String::from("abcd");
let string2 = "xyz";
let s: &'static str = "hello world"; //静态生命周期,存活于在整个程序运行

let result = longest(string1.as_str(), string2);
println!("{result}");
}

fn longest<'a>(x: &'a str, y: &'a str) -> &'a str { //'a 该返回值的生命周期与参数中较短的生命周期一样长
if x.len() > y.len() {
x
} else {
y
}
}

//struct定义中的生命周期注释
struct Import<'a> { //多用在含有引用的结构体
part: &'a str
}

//方法定义中的生命周期注解
impl<'a> Import<'a> {
fn level(&self) -> i32 {
3
}
}

三条规则(在没有显式生命周期注解时)

  • 编译器为每个输入类型中的每个生命周期分配不同的生命周期参数
  • 如果只有一个输入生命周期参数,该生命周期将被分配给所有的输出生命周期参数
  • 如果有多个输入生命周期参数,但其中一个是&sef或&mut self(因为这是一个方法),那么self的生命周期会被分配给所有的输出生命周期参数

编写测试

例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#[derive(Debug)]
struct Rectangle {
width: u32,
height: u32
}

impl Rectangle {
fn can_hold(&self, other: &Rectangle) -> bool {
self.width > other.width &&self.height > other.height
}
}

#[cfg(test)] //设置该测试代码只在cargo test生效
mod test {
use super::*; //应用模块外的内容

#[test]
fn larger_can_hold_smaller() {
let larger = Rectangle {
width: 8,
height: 7
};

let smaller = Rectangle {
width: 5,
height: 1
};
assert!(larger.can_hold(&smaller));
}

#[test]
fn larger_cannot_hold_smaller() {
let larger = Rectangle {
width: 8,
height: 7
};

let smaller = Rectangle {
width: 5,
height: 1
};
assert!(!smaller.can_hold(&larger));
}

//assert_eq!()测试相等断言,asser_ne!()测试不等断言
//断言失败显示提示信息:assert!(fun(), "失败信息")
//测试应该发生panic:在#[test]后加上#[should_panic(expected = "指定匹配发生的错误信息")]
}

执行与组织测试

测试命令的参数

  • 先列出cargo test的参数 cargo test –help
  • 然后跟着– cargo test – –help ,再列出Test binary(测试二进制文件)的参数

测试的默认运行模式:使用线程并行运行

必须确保:

  • 各个测试不互相依赖
  • 不依赖于共享的状态(包括环境:目录、环境变量等)

单线程测试:

1
cargo test -- --test-threads=1

在测试时将函数输出打印出来:

1
cargo test -- --show-output

运行指定的测试:

1
cargo test 函数名称(多个函数可以取其公有名称的部分)

在#[test]后加上#[ignore]后该测试默认不运行。

运行该被忽略的测试:

1
cargo test -- --ignored

或者全部运行:

1
cargo test -- --include-ignored

单元测试(Unit tests):小而集中的测试,每次只测试一个模块,并且可以测试私有接口

集成测试(Integration tests):完全外部的测试,它们以其他外部代码的方式使用你的代码,仅使用公共接口,并且可能
在一个测试中覆盖多个模块

如果项目只有binary crate(只有src/main.rs)不能创建集成测试

推荐的项目结构是:

  • src/main.rs保持简单,主要用于调用
  • src/Iib.rs包含主要逻辑

这样可以对ib.rs进行集成测试

原因是只有lib crate才能暴露函数供其他crate使用


学习rust_day08
https://zlsf-zl.github.io/2026/03/17/学习rust-day08/
作者
ZLSF
发布于
2026年3月17日
许可协议