掘金 后端 ( ) • 2024-05-07 13:33

theme: github

Rust,作为一门系统编程语言,以其内存安全和并发性能而著称。本文盘点 20 个惊艳的Rust单行代码,这些代码不仅简洁,而且充分展示了Rust的强大功能和优雅之处。喜欢的同学开收藏起来吧!

  1. 打印“Hello, World!”
println!("Hello, World!");

这是Rust中最简单的打印语句,用于输出文本到控制台。

  1. 定义一个不可变的静态字符串
static IMMUTABLE_STRING: &'static str = "This is an immutable string";

这行代码定义了一个静态的、不可变的字符串常量。

  1. 创建一个空的HashMap
let mut map = std::collections::HashMap::new();

使用Rust标准库中的HashMap结构创建一个空的哈希映射。

  1. 使用闭包对数组进行排序
let mut nums = vec![5, 2, 9, 1, 5, 6];
nums.sort_by(|a, b| a.cmp(b));

这里使用了闭包(匿名函数)来定义排序规则,对整数数组进行排序。

  1. 定义一个简单的枚举类型
enum Color { Red, Green, Blue }

这行代码定义了一个包含三个变体的枚举类型:Red、Green和Blue。

  1. 使用模式匹配解构枚举
let color = Color::Red;
match color {
    Color::Red => println!("It's red!"),
    _ => println!("It's not red!"),
}

通过模式匹配来解构枚举类型,并根据匹配结果执行相应的代码块。

  1. 使用Option类型处理可能的空值
let optional_value: Option<i32> = Some(42);

Option类型用于表示值可能存在或不存在,是Rust中处理空值的安全方式。

  1. 使用Result类型处理可能的错误
fn divide(a: i32, b: i32) -> Result<i32, &'static str> {
    if b == 0 { Err("Cannot divide by zero") } else { Ok(a / b) }
}

Result类型用于表示操作可能成功或失败,并附带相应的结果或错误信息。

  1. 定义一个简单的结构体
struct Point { x: i32, y: i32 }

这行代码定义了一个包含两个字段(x和y)的结构体。

  1. 实现一个简单的Trait
trait SayHello { fn say_hello(&self); }
impl SayHello for i32 { fn say_hello(&self) { println!("Hello from {}", self); } }

这里定义了一个Trait(特征)并为i32类型实现了这个特征。

  1. 使用线程安全的原子操作
use std::sync::atomic::{AtomicUsize, Ordering};
static ATOMIC_COUNTER: AtomicUsize = AtomicUsize::new(0);
ATOMIC_COUNTER.fetch_add(1, Ordering::SeqCst);

这行代码展示了如何使用Rust的原子操作来安全地在多线程环境中增加一个计数器。

  1. 使用生命周期注解确保内存安全
fn print_value<'a>(value: &'a str) { println!("{}", value); }

生命周期注解('a)用于确保引用的有效性,并防止悬垂引用和数据竞争。

  1. 定义一个简单的泛型函数
fn print_array<T: std::fmt::Debug>(array: &[T]) {
    for item in array { println!("{:?}", item); }
}

泛型函数可以接受不同类型的参数,只要这些类型实现了指定的Trait(在这里是Debug)。

  1. 使用宏来简化代码
macro_rules! println_twice { ($($arg:tt)*) => { println!($($arg)*); println!($($arg)*); } }
println_twice!("Hello, Macro!");

Rust的宏功能强大,可以用于生成重复的代码模式,提高代码的可读性和可维护性。

  1. 使用闭包捕获环境变量
let outer_var = 10;
let closure = || println!("Captured value: {}", outer_var);
closure();

闭包可以捕获其定义环境中的变量,使其在被调用时能够访问这些变量。

  1. 使用Box动态分配内存
let b = Box::new(5);
println!("Boxed value: {}", *b);

Box用于在堆上动态分配内存,并返回一个指向该内存的指针。

  1. 定义一个简单的异步函数
async fn say_hello() { println!("Hello from async function!"); }

异步函数可以在不阻塞当前线程的情况下执行异步操作。

  1. 使用unsafe块执行不安全代码
unsafe { println!("Unsafe code block!"); }

unsafe块允许执行可能违反Rust内存安全保证的代码,应谨慎使用。

  1. 使用Raw指针操作内存
let raw_ptr: *const i32 = &10 as *const i32;
unsafe { println!("Raw pointer value: {}", *raw_ptr); }

Raw指针提供了对内存的直接访问,但需要谨慎处理以避免内存安全问题。

  1. 使用特性(Trait)对象进行动态分发
trait Animal { fn speak(&self); }
struct Dog; impl Animal for Dog { fn speak(&self) { println!("Woof!"); } }
let animal: &dyn Animal = &Dog as &dyn Animal; animal.speak();

特性(Trait)对象允许在运行时动态确定实际调用的方法实现,实现动态分发。这种机制类似于其他语言中的接口或抽象类。通过使用&dyn Trait语法,我们可以创建一个指向实现了特定Trait的任意类型的引用,并在运行时确定实际调用的方法实现。这种方式提供了更大的灵活性,允许我们编写更加通用和可重用的代码。在上述代码中,我们定义了一个Animal Trait和一个实现了该Trait的Dog结构体。然后,我们创建了一个指向dyn Animal的特性对象引用,并将其指向Dog实例。最后,我们调用该引用的speak()方法,该方法会在运行时动态分发到Dog的speak()实现上。