Rust新特性学习笔记(还有忘了的东西嘻嘻)
星期五, 11月 29, 2024 | 3分钟阅读 | 更新于 星期四, 1月 9, 2025
妈的,Rust怎么迭代这么快啊。。。。
标签系统
不知道这是啥时候出来的特性,可以在循环内使用,可以直接break
。
fn main() {
let s = [[5, 6, 7], [8, 9, 10], [21, 15, 32]];
let mut elements_searched = 0;
let target_value = 10;
'outer: for i in [0, 1, 2] {
for j in 0..=2 {
elements_searched += 1;
if s[i][j] == target_value {
break 'outer;
}
}
}
print!("elements searched: {elements_searched}");
}
代码块
抽象的东西,奶奶的。用大括号括起来的叫做代码块。每个块有value
和type
。
let x = { // 这是一个代码块
let y = 10;
println!("y: {y}");
z - y //最后一个数值被赋予给x
};
作用域
Rust安全的原因就是这个,变量拥有作用域,也就是变量只作用于一个封闭的代码空间。
fn main() {
let a = 10;
println!("before: {a}");
{
let a = "hello";
println!("inner scope: {a}");
let a = true;
println!("shadowed in inner scope: {a}");
}
println!("after: {a}");//最先的变量a的作用域包含整个大的代码块,它不会被小的代码块遮蔽,所以最后的print仍为10
}
现在函数返回值不需要使用return
也可以
fn gcd(a: u32, b: u32) -> u32 {
if b > 0 {
gcd(b, a % b)
} else {
a
}
}
Rust常用的宏
-
println!
标准输出,自带换行,不换行使用
print!
-
format!
字符串形式输出
-
dbg!
记录某个值然后输出,用在debug
-
todo!
标记未实现的代码区域,运行会
panic
-
unreachable!
无法访问的代码区域,运行会
panic
Rust数组和元祖
- Rust的数组可以使用美观打印以保证数组易读性,使用
{:?}
- 元组将多种类型的值组合成复合类型,使用
()
包裹。
Rust模式匹配
- 模式匹配使用
match 变量 {}
,与switch类似 - 可以在代码块中定义一些判断,如
key if key.is_lowercase() => println!("Lowercase: {key}")
_
为模式匹配的通配符,负责显示所有情况
解构
- 解构就是把复合类型分解成组成部分的过程
- 解构一般使用
模式匹配
实现 - 解构结构体:
struct Foo {
x: (u32, u32), //定义元组
y: u32,
}
#[rustfmt::skip] //跳过格式化的宏
fn main() {
let foo = Foo { x: (1, 2), y: 3 };
match foo {
Foo { x: (1, b), y } => println!("x.0 = 1, b = {b}, y = {y}"),//匹配x元组第一个元素为1,则把第二个元素赋给b,把y字段赋值给y
Foo { y: 2, x: i } => println!("y = 2, x = {i:?}"),//与上部分类似
Foo { y, .. } => println!("y = {y}, other fields were ignored"),//`..`表示忽略其他情况
}
}
let控制流
- 除了match,还可以使用
let
表达式实现模式匹配,以及解构 - if let表达式:
use std::time::Duration;
fn sleep_for(secs: f32) {
if let Ok(dur) = Duration::try_from_secs_f32(secs) {
std::thread::sleep(dur);
println!("slept for {:?}", dur);
}
}
fn main() {
sleep_for(-10.0);
sleep_for(0.8);
}
- let else表达式
fn hex_or_die_trying(maybe_string: Option<String>) -> Result<u32, String> {
let s = if let Some(s) = maybe_string {
s
} else {
return Err(String::from("got None"));
};
let first_byte_char = if let Some(first_byte_char) = s.chars().next() {
first_byte_char
} else {
return Err(String::from("got empty string"));
};
if let Some(digit) = first_byte_char.to_digit(16) {
Ok(digit)
} else {
Err(String::from("not a hex digit"))
}
}
fn main() {
println!("result: {:?}", hex_or_die_trying(Some(String::from("foo"))));
}
重要 如需了解匹配模式并从函数返回的常见情况,请使用 let else。“else” 分支必须执行不同的结束方式(例如,return、break 或 panic,但不能直接执行到代码块的末尾)。
- while let表达式 while let与if let类似,只是会重复测试一个值
fn main() {
let mut name = String::from("Comprehensive Rust 🦀");
while let Some(c) = name.pop() {
println!("character: {c}");
}
}
方法和特征
- 方法
Rust允许将函数与新类型相关联,使用
impl
包裹,例子如下:
#[derive(Debug)]
struct Race {
name: String,
laps: Vec<i32>, //动态数组存圈数
}
impl Race {
// 静态方法
fn new(name: &str) -> Self {
Self {
name: String::from(name),
laps: Vec::new(),
}
}
// 可变借用,修改结构体
fn add_lap(&mut self, lap: i32) {
self.laps.push(lap);
}
// 不可变借用,只读访问
fn print_laps(&self) {
println!("Recorded {} laps for {}:", self.laps.len(), self.name);
for (idx, lap) in self.laps.iter().enumerate() {
println!("Lap {idx}: {lap} sec");
}
}
// 获取所有权,消耗实例
fn finish(self) {
let total: i32 = self.laps.iter().sum();
println!("Race {} is finished, total lap time: {}", self.name, total);
}
}
fn main() {
let mut race = Race::new("Monaco Grand Prix");
race.add_lap(70);
race.add_lap(68);
race.print_laps();
race.add_lap(71);
race.print_laps();
race.finish();
// race.add_lap(42);//已被finish消耗了,再调用会编译错误
}
self
参数指定receiver
- 该方法作用的对象。方法有几种常见的receiver:
&self
:使用不可变的共享引用从调用方借用对象。之后可以再次使用该对象。&mut self
:使用唯一的可变引用从调用方借用对象。之后可以再次使用该对象。self
:获取对象的所有权并将其从调用方移出。该方法会成为对象的所有者。除非明确转移对象的所有权,否则在该方法返回时,对象将被丢弃(取消分配)。具备完全所有权,不自动等同于具备可变性。mut self
:同上,但该方法可以改变对象。无receiver
:这将变为结构体上的静态方法。通常用于创建构造函数,按惯例被称为new
。
实现结果:
Recorded 2 laps for Monaco Grand Prix:
Lap 0: 70 sec
Lap 1: 68 sec
Recorded 3 laps for Monaco Grand Prix:
Lap 0: 70 sec
Lap 1: 68 sec
Lap 2: 71 sec
Race Monaco Grand Prix is finished, total lap time: 209