Rust 入门笔记 —— 流程控制
1. 分支
rust 的 if/else 和 go 的类似
- 即使是单句也不能缺少大括号
- 条件可以不用括号包裹
// Fill in the blanks
fn main() {
let n = 5;
if n < 0 {
println!("{} is negative", n);
} else if n > 0 {
println!("{} is positive", n);
} else {
println!("{} is zero", n);
}
}
rust 的 if/else 结构可以用来赋值
// Fix the errors
fn main() {
let n = 5;
let big_n =
if n < 10 && n > -10 {
println!(", and is a small number, increase ten-fold");
10 * n
} else {
println!(", and is a big number, halve the number");
n / 2
};
println!("{} -> {}", n, big_n);
}
2 循环
2.1 for
这个 for 和 py 的 for 比较类似,是一个 foreach 型的
fn main() {
for n in 1..100 { // modify this line to make the code work
if n == 100 {
panic!("NEVER LET THIS RUN")
}
}
println!("Success!");
}
当遍历数组的时候,循环变量会获得被遍历的所有权(但是基本类型还是复制的)
let names = [String::from("liming"),String::from("hanmeimei")];
for name in names {
// Do something with name...
}
println!("{:?}", names); // wrong! borrow of moved value: `names`
所以我们可以用切片来遍历引用
let names = [String::from("liming"),String::from("hanmeimei")];
for name in &names {
// Do something with name...
}
println!("{:?}", names);
通过数组的iter.enumrate方法,可以获得(index, value)的 tuple
fn main() {
let a = [4, 3, 2, 1];
// Iterate the indexing and value in 'a'
for (i,v) in a.iter().enumerate() {
println!("The {}th element is {}",i+1,v);
}
}
2.2 while
while 循环和 C 的 while 是一样的,不过条件还是可以不加括号
// Fill in the blanks to make the last println! work !
fn main() {
// A counter variable
let mut n = 1;
// Loop while the condition is true
while n < 10 {
if n % 15 == 0 {
println!("fizzbuzz");
} else if n % 3 == 0 {
println!("fizz");
} else if n % 5 == 0 {
println!("buzz");
} else {
println!("{}", n);
}
n += 1;
}
println!("n reached {}, so loop is over",n);
}
Rust也有 continue 和 break 关键字
Rust 使用 loop 代替 while true
// Fill in the blanks
fn main() {
let mut count = 0u32;
println!("Let's count until infinity!");
// Infinite loop
loop {
count += 1;
if count == 3 {
println!("three");
// Skip the rest of this iteration
continue;
}
println!("{}", count);
if count == 5 {
println!("OK, that's enough");
break;
}
}
assert_eq!(count, 5);
println!("Success!");
}
loop是一个表达式,所以 break 可以用来返回值
// Fill in the blank
fn main() {
let mut counter = 0;
let result = loop {
counter += 1;
if counter == 10 {
break counter * 2;
}
};
assert_eq!(result, 20);
println!("Success!");
}
通过 label 的方式,可以精确地 break 或 continue 嵌套循环
// Fill in the blank
fn main() {
let mut count = 0;
'outer: loop {
'inner1: loop {
if count >= 20 {
// This would break only the inner1 loop
break 'inner1; // `break` is also works.
}
count += 2;
}
count += 5;
'inner2: loop {
if count >= 30 {
// This breaks the outer loop
break 'outer;
}
// This will continue the outer loop
continue 'outer;
}
}
assert!(count == 30);
println!("Success!");
}
3 模式匹配
3.1 match
match有点类似于 C 的 switch,其基本形式如下
match target {
pattern1 => experssion1,
pattern2 => {
sth;
expression
},
_ => expression
}
match需要穷举出所有的可能,用_代表所有未列出的可能(类似于 default)
match 的分支必须是表达式,且分支表达式的类型必须相同
pattern 可以用 X|Y的形式表示,代表 X 或 Y
// 填空
enum Direction {
East,
West,
North,
South,
}
fn main() {
let dire = Direction::South;
match dire {
Direction::East => println!("East"),
Direction::South|Direction::North => { // 在这里匹配 South 或 North
println!("South or North");
},
_ => println!("West"),
};
}
match 本身也是一个表达式,因此可以用来赋值
fn main() {
let boolean = true;
// 使用 match 表达式填空,并满足以下条件
//
// boolean = true => binary = 1
// boolean = false => binary = 0
let binary = match boolean {
true => 1,
false => 0,
};
assert_eq!(binary, 1);
}
match可以取出模式中绑定的值,还记得我们的 enum 类型么
// 填空
enum Message {
Quit,
Move { x: i32, y: i32 },
Write(String),
ChangeColor(i32, i32, i32),
}
fn main() {
let msgs = [
Message::Quit,
Message::Move{x:1, y:3},
Message::ChangeColor(255,255,0)
];
for msg in msgs {
show_message(msg)
}
}
fn show_message(msg: Message) {
match msg {
Message::Move{x: a, y: b} => { // 这里匹配 Message::Move
assert_eq!(a, 1);
assert_eq!(b, 3);
},
Message::ChangeColor(_, g, b) => {
assert_eq!(g, 255);
assert_eq!(b, 0);
}
__ => println!("no data in these variants")
}
}
3.2 if let
if let 对应于只有一个模式需要处理的情况,这时候用 match 需要写一个无用的 default
下面两份代码等价
fn main() {
let o = Some(7);
// 移除整个 `match` 语句块,使用 `if let` 替代
match o {
Some(i) => {
println!("This is a really long string and `{:?}`", i);
}
_ => {}
};
}
fn main() {
let o = Some(7);
if let Some(i) = o {
println!("This is a really long string and `{:?}`", i);
}
}
3.3 matches!
Rust提供了一个宏 matches,把表达式和模式进行匹配,返回是否匹配
let foo = 'f';
println!("{}", matches!(foo, 'A'..='Z' | 'a' ..= 'z')) // true
enum MyEnum {
Foo,
Bar
}
fn main() {
let mut count = 0;
let v = vec![MyEnum::Foo,MyEnum::Bar,MyEnum::Foo];
for e in v {
// if e == MyEnum::Foo { // 修复错误,只能修改本行代码
if matches!(e, MyEnum::Foo) {
count += 1;
}
}
assert_eq!(count, 2);
}
评论 (0)