Rust 编程小技巧摘选(7)

简介: Rust 编程小技巧摘选(7)

Rust 编程小技巧(7)

1. 交换变量

与python, go等语言用法类似,不同的是rust不能省掉元组的括号 () 。

fn main() {
    let a = 3;
    let b = 23;
    println!("a: {}, b: {}", a, b);
    let (a, b) = (b, a);
    println!("a: {}, b: {}", a, b);
}

输出:

a: 3, b: 23

a: 23, b: 3

2. 翻转数组

fn main() {
    let x = vec!["Hello", "World"];
    let y: Vec<_> = x.iter().rev().collect();
    println!("{:?}\n{:?}", x, y);
    let mut z = vec![1,2,3];
    println!("{:?}", z);
    z.reverse();
    println!("{:?}", z);
}

输出:

["Hello", "World"]

["World", "Hello"]

[1, 2, 3]

[3, 2, 1]

3. for_each() 用法

fn main() {
    // 迭代一个 vec 并打印每个元素  
    let vec = vec![1, 2, 3, 4, 5];  
    vec.iter().for_each(|x| print!("{} ", x));
    println!();
    // 迭代一个字符串并打印每个字符  
    let s = "hello";  
    s.chars().for_each(|c| print!("{} ", c));
    println!();
    // 迭代一个 vec 并将其元素加倍  
    let mut v1 = vec![1, 2, 3, 4, 5];
    let mut v2 = vec![];
    v1.iter().for_each(|x| v2.push(x * 2));  
    println!("{:?}", v2);
    v1.clone().iter().for_each(|x| v1.push(x * 2));  
    println!("{:?}", v1);
}

输出:

1 2 3 4 5

h e l l o

[2, 4, 6, 8, 10]

[1, 2, 3, 4, 5, 2, 4, 6, 8, 10]

4. 结构体 Display trait

结构体的两种形式,对应的成员取法不同;

前者用 self.成员变量名 self.x, self.y;后者用 self.成员索引号 self.0, self.1, self.2, ......

use std::fmt::Display;
use std::fmt::Result;
use std::fmt::Formatter;
struct Point {
    x: f64,
    y: f64,
}
struct Point2(f64, f64);
impl Display for Point {
    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
        write!(f, "({}, {})", self.x, self.y)
    }
}
impl Display for Point2 {
    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
        write!(f, "({}, {})", self.0, self.1)
    }
}
fn main() {
    let p = Point { x: 2.0, y: -3.5 };
    println!("{}", p);
    let p = Point2(2.0, -3.5);
    println!("{}", p);
}

输出:

(2, -3.5)

(2, -3.5)

5. HashMap 和 BTreeMap

两者都是 Rust 中的哈希表数据结构,它们的相同点:

都支持使用 Vec 或 String 作为键,也支持使用标准库中的其他结构体作为键。

都支持使用 Option 类型作为键值对中的值。

都支持使用 HashMap 类型的成员函数来进行基本的操作,例如插入、删除、查找、更新等。

不同点:

HashMap 使用哈希表(HashMap)算法来存储键值对,而 BTreeMap 使用 B-TREE(B 树)算法来存储键值对。因此,BTreeMap 在查找、插入、删除等操作上的性能比 HashMap 更好。

如果需要使用哈希表(HashMap)数据结构,但不需要按照键值对的顺序来访问,而且对查找、插入、删除等操作的性能要求不高,那么可以使用 HashMap。如果需要使用哈希表(HashMap)数据结构,而且对查找、插入、删除等操作的性能要求较高,而且需要按照键值对的顺序来访问,那么可以使用 BTreeMap。

示例:

use std::collections::BTreeMap;
use std::collections::HashMap;
fn main() {
    let mut x = BTreeMap::new();
    x.insert("one", 1);
    x.insert("two", 2);
    println!("{:?}", x);
    let x: HashMap<&str, i32> = [
        ("one", 1),
        ("two", 2),
    ].iter().cloned().collect();
    println!("{:?}", x);
}

输出:

{"one": 1, "two": 2}

{"one": 1, "two": 2}

6. 遍历输出哈希表

在for...in...循环结构中使用元组(k, v)读取对应键值对:

use std::collections::BTreeMap;
use std::collections::HashMap;
fn main() {
    let mut x = BTreeMap::new();
    x.insert("one", 1);
    x.insert("two", 2);
    x.insert("three", 3);
    x.insert("four", 4);
    for (k, v) in &x {
        println!("Key={}, Value={}", k, v);
    }
    println!();
    let x: HashMap<&str, i32> = [
        ("one", 1),
        ("two", 2),
        ("three", 3),
        ("four", 4),
    ].iter().cloned().collect();
    for (k, v) in &x {
        println!("Key={key}, Value={val}", key = k, val = v);
    }
}

输出:

Key=four, Value=4

Key=one, Value=1

Key=three, Value=3

Key=two, Value=2

Key=three, Value=3

Key=two, Value=2

Key=one, Value=1

Key=four, Value=4

7. 分离奇数和偶数

.filter() 方法是一个在标准库中的std::iter::Iterator trait的默认方法。这个方法会创建一个新的迭代器,包含所有满足给定条件的元素。

示例:分离一个数组中的奇数和偶数

fn main() {
    let mut vec = vec![1, 2, 3, 4, 5];  
    vec.clone().iter().for_each(|x| vec.push(x + 5));  
    println!("{:?}", vec);
    fn is_even(x: &i32) -> bool { *x % 2 == 0 }
    fn print_x(x: &i32) { print!("{} ", x) }
    vec.iter().filter(|x| !is_even(x)).for_each(|x| print_x(x));
    println!();
    vec.iter().filter(|x| is_even(x)).for_each(|x| print_x(x));
    println!();
}

输出:

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

1 3 5 7 9

2 4 6 8 10  

8. 判断素数(质数)

.any() 方法是一个在标准库中的std::iter::Iterator trait的默认方法。这个方法会检查迭代器中是否有元素满足给定的条件,如果有元素满足条件,它就会返回true,否则返回false。

示例:求30以内的质数

fn is_prime(n: u64) -> bool {
    match n {
        0..=1 => false,
        _ => !(2..n).any(|d| n % d == 0),
    }
}
fn main() {
    for i in 1..=30 {
        if is_prime(i) {
            print!("{} ", i);
        }
    }
    println!();
}

输出:

2 3 5 7 11 13 17 19 23 29

目录
相关文章
|
1月前
|
Java
CSDN每日一练(Java)--小艺的英文名
CSDN每日一练(Java)--小艺的英文名
|
1月前
|
存储 C语言 索引
环形链表、环形链表 II、有效的括号​​​​​​​【LeetCode刷题日志】
环形链表、环形链表 II、有效的括号​​​​​​​【LeetCode刷题日志】
|
4天前
|
Rust 安全 测试技术
Rust并发编程实践:快速入门系统级编程
Rust是一门现代的系统编程语言,它的设计目标是提供安全性、并发性和高性能。Rust的出现是为了解决其他编程语言在这些方面存在的一些问题和挑战。
|
1月前
|
存储 Java
Java链表
Java链表
11 0
|
1月前
|
算法 索引
LeetCode刷题---142. 环形链表 II(双指针-快慢指针)
LeetCode刷题---142. 环形链表 II(双指针-快慢指针)
|
1月前
|
算法 索引
LeetCode刷题---141. 环形链表(双指针-快慢指针)
LeetCode刷题---141. 环形链表(双指针-快慢指针)
|
1月前
|
算法 Java 索引
[Java·算法·简单] LeetCode 141. 环形链表 详细解读
[Java·算法·简单] LeetCode 141. 环形链表 详细解读
23 0
|
1月前
|
存储 算法 Java
【数据结构与算法】2、链表(简单模拟 Java 中的 LinkedList 集合,反转链表面试题)
【数据结构与算法】2、链表(简单模拟 Java 中的 LinkedList 集合,反转链表面试题)
43 0
|
2月前
|
Java
|
2月前
|
Java
LeetCode题解- 两两交换链表中的节点-Java
两两交换链表中的节点-Java
13 0