Rust 是一种系统编程语言,它在设计时融合了多种创新的概念和构思,以确保内存安全、并发安全和提供现代编程的便利性。本文盘点 Rust 中令人惊叹的天才构思,以及它们背后的代码和含义。话不多说,让我们开启这段神奇之旅吧~
所有权系统(Ownership System)
Rust 的所有权系统是其最核心的特性之一,它通过编译时检查来保证内存安全。
fn main() {
let s = "hello"; // s 拥有 "hello" 的所有权
// s 离开作用域后,"hello" 将自动被丢弃
}
在这个简单的例子中,变量 s 拥有它所指向的字符串的所有权。当 s 离开作用域时,它所指向的数据会被自动清理。
生命周期(Lifetimes)
生命周期是 Rust 中用于描述引用有效性的概念。
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
if x.len() > y.len() { x } else { y }
}
longest 函数接受两个字符串切片的引用,并返回一个生命周期为 'a 的字符串切片引用。这意味着返回的引用与输入的两个引用一样长。
特征(Traits)
特征是 Rust 中的抽象类型,它们允许为不同类型定义共同的行为。
trait Drawable {
fn draw(&self);
}
impl Drawable for Circle {
fn draw(&self) {
// 绘制圆形
}
}
这里定义了一个 Drawable 特征和一个实现了 Drawable 的 Circle 结构体。impl 关键字用于为特定类型实现特征。
泛型(Generics)
泛型允许定义函数和类型时不指定具体的类型,从而提高代码的复用性。
fn identity<T>(value: T) -> T {
value
}
identity 函数是一个泛型函数,它接受任何类型的参数并返回相同的值。
迭代器(Iterators)
迭代器提供了一种处理序列数据的抽象方式。
let nums = vec![1, 2, 3, 4, 5];
let even_nums: Vec<i32> = nums.into_iter().filter(|&x| x % 2 == 0).collect();
这段代码使用迭代器、闭包和 collect 方法来创建一个只包含偶数的 Vec。
闭包(Closures)
闭包是 Rust 中的匿名函数,它们可以捕获并使用外部环境中的变量。
let add_one = |x: i32| x + 1;
let res = add_one(5);
这里定义了一个闭包 add_one,它接受一个 i32 类型的参数并返回该参数加一的结果。
错误处理(Error Handling)
Rust 使用 Result 类型来处理错误,而不是通过异常。
fn divide(a: f64, b: f64) -> Result<f64, String> {
if b == 0.0 {
Err("Cannot divide by zero".to_string())
} else {
Ok(a / b)
}
}
divide 函数在除数为零时返回一个 Err,否则返回 Ok 包裹的商。
并发编程(Concurrency)
Rust 的标准库提供了多种并发编程的原语,如线程和通道。
use std::thread;
let handle = thread::spawn(|| {
println!("Hello from a thread!");
});
handle.join().unwrap();
这段代码创建了一个新的线程,并在其中打印了一条消息。join 方法等待线程完成。
智能指针(Smart Pointers)
智能指针是 Rust 中用于封装和管理内存的指针类型。
use std::rc::Rc;
let a = Rc::new(42);
let b = Rc::clone(&a);
Rc<T> 是一个引用计数的智能指针,允许多个指针引用同一数据。
模式匹配(Pattern Matching)
模式匹配是 Rust 中处理数据结构的一种强大工具。
enum Message {
Quit,
Move { x: i32, y: i32 },
Write(String),
}
match msg {
Message::Quit => return,
Message::Move { x, y } => println!("Move to x = {}, y = {}", x, y),
Message::Write(text) => println!("Write: {}", text),
}
这里使用 match 表达式来处理不同的消息类型。
宏(Macros)
宏是 Rust 的一个强大特性,允许代码生成代码。
macro_rules! my_macro {
() => {
// 宏展开的代码
};
}
my_macro!();
my_macro 是一个简单的宏,它在调用时会展开为大括号内的代码。
条件编译(Conditional Compilation)
条件编译允许根据不同的平台或配置编译不同的代码。
#[cfg(target_os = "windows")]
fn is_windows() -> bool {
true
}
这个属性宏仅在目标操作系统是 Windows 时启用 is_windows 函数。
裸指针(Raw Pointers)
裸指针提供了对内存的底层控制,但需要开发者手动保证安全。
let mut nums: [i32; 3] = [1, 2, 3];
let raw_ptr: *const i32 = nums.as_ptr();
这段代码获取了数组 nums 的裸指针。
Unions
Unions 允许不同的数据类型共享内存。
union MyUnion {
i: i32,
f: f32,
}
MyUnion 可以存储一个 i32 或一个 f32,但一次只能存储一个。
常量泛型(Const Generics)
常量泛型允许在编译时使用常量值来参数化类型。
struct Array<T, const N: usize> {
data: [T; N],
}
这里定义了一个 Array 结构体,它的第二个类型参数是一个编译时常量,指定了数组的长度。
异步编程(Async Programming)
Rust 的异步编程模型允许编写非阻塞的 I/O 密集型代码。
async fn fetch_data() -> Result<String, std::io::Error> {
let data = reqwest::get("https://example.com").await?.text().await?;
Ok(data)
}
fetch_data 是一个异步函数,它使用 await 来挂起当前任务直到网络请求完成。
内存分配(Memory Allocation)
Rust 允许开发者定义自己的内存分配器。
use std::alloc::{GlobalAlloc, Layout};
unsafe impl GlobalAlloc for MyAllocator {
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
// 分配内存的代码
}
}
这里定义了一个自定义的全局分配器 MyAllocator。
类型推断(Type Inference)
Rust 的类型推断系统可以减少代码中的类型注解。
let mut vec = Vec::new();
vec.push(1); // 编译器推断出 vec 的类型是 Vec<i32>
零成本抽象(Zero-Cost Abstractions)
Rust 的许多抽象都是零成本的,这意味着它们不会引入运行时开销。
struct Wrapper<T>(T);
impl<T> Wrapper<T> {
fn new(value: T) -> Self {
Wrapper(value)
}
}
Wrapper 是一个简单的泛型结构体,它的构造函数 new 不会产生额外的开销。
模块系统(Module System)
Rust 的模块系统提供了一种将代码组织成层次结构的方式。
mod my_module {
pub fn do_something() {
// ...
}
}
my_module::do_something();
这里 my_module 是当前文件中的一个模块,它包含了可以被外部访问的 do_something 函数。
特征门控(Feature Gates)
特性门控是一种防止某些特性被滥用的方法。
#![feature(untagged_unions)]
这个属性宏启用了 untagged_unions 这个尚未稳定的 Rust 特性。
静态断言(Static Assertions)
静态断言允许在编译时检查某些条件是否为真。
const_assert_eq!(42, 42); // 编译时检查两个常量是否相等
如果 const_assert_eq! 宏中的两个表达式不相等,编译将失败。
枚举的模式匹配(Enum Pattern Matching)
枚举是 Rust 中强大的数据结构,可以与模式匹配结合使用。
enum Animal {
Dog,
Cat,
Bird,
}
fn make_sound(animal: Animal) {
match animal {
Animal::Dog => println!("Woof!"),
Animal::Cat => println!("Meow!"),
Animal::Bird => println!("Tweet!"),
}
}
make_sound 函数根据传入的 Animal 枚举值打印出不同的声音。
类型状态转换(Type State Transformation)
通过 Option 和 Result 类型,Rust 允许开发者表达值的存在状态或操作的成功状态。
fn try_divide(a: i32, b: i32) -> Result<i32, String> {
if b == 0 {
Err("Cannot divide by zero".to_string())
} else {
Ok(a / b)
}
}
这个函数使用 Result 来表示除法操作可能成功(Ok)或失败(Err)。
裸指针的安全性(Safety of Raw Pointers)
Rust 允许使用裸指针,但要求使用 unsafe 代码块,以明确指出潜在的不安全操作。
unsafe {
let mut num: i32 = 10;
let raw_ptr: *mut i32 = &mut num;
*raw_ptr += 1;
}
在这个 unsafe 块中,我们直接通过裸指针修改了 num 的值。
迭代器适配器(Iterator Adapters)
迭代器适配器为迭代器提供了链式调用的能力,用于构建复杂的迭代逻辑。
let a = [1, 2, 3, 4, 5];
let sum: i32 = a.iter().filter(|&&x| x % 2 == 0).sum();
这里使用迭代器适配器 filter 和 sum 来计算切片中所有偶数的和。
异步代码的同步执行(Asynchronous Code Synchronization)
通过 .await 和 async/await 语法,Rust 允许同步风格的异步编程。
async fn async_task() {
println!("Doing something asynchronously...");
}
async fn main() {
let handle = async_task();
handle.await;
}
async_task 是一个异步函数,main 函数通过 .await 等待它的完成。
FFI(Foreign Function Interface)
Rust 可以安全地与 C 语言代码进行互操作。
extern "C" {
fn abs(input: i32) -> i32;
}
fn main() {
let result = unsafe { abs(-1) };
println!("The absolute value is {}", result);
}
这里通过 extern 块声明了对 C 语言中 abs 函数的引用。
宏的规则系统(Macro_rules!)
宏允许开发者定义新的语法规则。
#[macro_export]
macro_rules! my_macro {
($val:expr) => {
println!("The value is: {}", $val);
};
}
fn main() {
my_macro!(42);
}
my_macro 是一个宏,它接受一个表达式并打印出来。
作者:python落日圆
链接:https://juejin.cn/post/7364224622679965730
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。