Rust 编程小技巧(6)
1. 打印字符串
fn main() { println!("Hello, world"); let s = "Rust"; print!("{}", s); println!(); }
Rust 打印主要用宏 print!()、println!(),打印宏的占位符使用 {}。
2. 重复打印字串
有多种方法,比如使用:循环、string.repeat()、vector.join()等等。
fn main() { for _ in 0..8 { print!("rust"); } println!("\n{}", "rust".repeat(8)); let s = vec!["rust"; 8]; println!("{:?}", s); println!("{}", s.join("")); println!("{}", s.join(".")); }
输出:
rustrustrustrustrustrustrustrust
rustrustrustrustrustrustrustrust
["rust", "rust", "rust", "rust", "rust", "rust", "rust", "rust"]
rustrustrustrustrustrustrustrust
rust.rust.rust.rust.rust.rust.rust.rust
3. 自定义函数
比如,一个整数的平方、绝对值
fn square(x: i32) -> i32 { x * x } fn abs(x: i32) -> i32 { if x < 0 { return -x; } x } fn main() { let n = square(9); println!("{}", n); println!("{}", abs(-10)); }
rust 函数的返回关键字 return,在最后的出口可以省略,只需一个表达式(不用分号结尾)。
4. 遍历动态数组
.into_iter() 转迭代器
fn main() { let items = vec![11, 22, 33]; for x in items.clone().into_iter() { do_something(x); } items.clone().into_iter().for_each(|x| do_something(x)); println!("{:?}", items); } fn do_something(n: i64) { println!("Number {}", n) }
输出:
Number 11
Number 22
Number 33
Number 11
Number 22
Number 33
[11, 22, 33]
5. 遍历二维数组
.iter() 创建迭代器
fn main() { let vec = vec![vec![1, 2], vec![3, 4], vec![5, 6]]; for outer_iter in vec.iter() { for inner_iter in outer_iter.iter() { print!("{} ", inner_iter); } } println!(); vec.iter().for_each(|x| x.iter().for_each(|y| print!("{} ", y))); println!(); }
6. 同时遍历索引和值
.enumerate() 枚举
fn main() { test1(); test2(); } fn test1() { let items = ["a", "b", "c"]; for (i, x) in items.iter().enumerate() { println!("Item {} = {}", i, x); } } fn test2() { let items = ["a", "b", "c"]; items.iter().enumerate().for_each(|(i, x)| { println!("Item {} = {}", i, x); }); }
7. 检查数组是否包含某个值
代码1:for ... in 遍历
fn contain(list: &[i32], num: i32) { let mut flag = false; for &i in list { if i == num { flag = true; break; } } if flag { println!("{:?} 包含 {}", list, num); } else { println!("{:?} 不含 {}", list, num); } } fn main() { let list = [1, 2, 3]; let num = 0; contain(&list, num); let num = 2; contain(&list, num); }
代码2: 迭代器 + any()方法
fn contain(list: &[i32], num: i32) { let flag = list.iter().any(|&item| item == num); if flag { println!("{:?} 包含 {}", list, num); } else { println!("{:?} 不含 {}", list, num); } } fn main() { let list = [1, 2, 3]; let num = 0; contain(&list, num); let num = 2; contain(&list, num); }
代码3: 直接用包含方法 contains()
fn contain(list: &[i32], num: i32) { if list.contains(&num) { println!("{:?} 包含 {}", list, num); } else { println!("{:?} 不含 {}", list, num); } } fn main() { let list = [1, 2, 3]; let num = 0; contain(&list, num); let num = 2; contain(&list, num); }
输出:
[1, 2, 3] 不含 0
[1, 2, 3] 包含 2
8. 二维矩阵中查找某个值
fn search<T: Eq>(m: &Vec<Vec<T>>, x: &T) -> Option<(usize, usize)> { for (i, row) in m.iter().enumerate() { for (j, col) in row.iter().enumerate() { if *col == *x { return Some((i, j)); } } } None } fn main() { let v = vec![ vec![1, 2, 3], vec![4, 5, 6], vec![7, 8, 9], ]; println!("{:?}", search(&v, &6)); println!("{:?}", search(&v, &0)); }
输出:
Some((1, 2))
None
附:迭代器方法的区别
.into_iter() 和 .iter() 两个方法都用于创建迭代器,它们的区别在于:
1.所有权转移:.into_iter() 方法会消耗当前的集合,并将所有权转移给迭代器。这意味着在迭代完成后,原集合将不再可用。而 .iter() 方法不会消耗集合,它只是创建一个新的迭代器,你可以在迭代完成后继续使用原集合。
2.消耗和产生元素:.into_iter() 会消耗集合中的元素,并将它们放入迭代器中。这意味着每次调用迭代器的 next() 方法都会消耗集合中的一个元素。而 .iter() 只是产生元素的引用,并不会消耗集合中的元素。
3.用途:当你需要遍历集合中的元素并获取它们的所有权时,应该使用 .into_iter()。当你只需要读取集合中的元素而不消耗它们时,应该使用 .iter()。