Rust全局变量、宏编程与asnyc/await异步编程

目录全局变量错误处理unsafeRustmacro宏编程asnyc/await异步编程全局变量全局变量是在整个程序范围内可见的变量。虽然Rust强调模块化和封装,但在某些情况下,全局变量仍然有其用途。定义全局变量//定义全局变量staticCOUNTER:u32

目录


全局变量

全局变量是在整个程序范围内可见的变量。虽然 Rust 强调模块化和封装,但在某些情况下,全局变量仍然有其用途。

定义全局变量

// 定义全局变量
static COUNTER: u32 = 0;

fn increment_counter() {
    COUNTER += 1;
}

fn main() {
    increment_counter();
    println!("Counter: {}", COUNTER);
}

可变全局变量 在 Rust 中,默认情况下全局变量是不可变的。如果需要可变全局变量,可以使用 static mut 关键字。

// 定义可变全局变量
static mut COUNTER: u32 = 0;

fn increment_counter() {
    unsafe {
        COUNTER += 1;
    }
}

fn main() {
    increment_counter();
    println!("Counter: {}", COUNTER);
}

错误处理

错误处理概述

Rust 提供了多种错误处理机制,包括:

  • Result 类型: 表示可能出错的操作。
  • Option 类型: 表示可能不存在的值。
  • panic! 宏: 用于处理不可恢复的错误。
  • 自定义错误类型: 可以定义自己的错误类型来更好地描述错误。

Result 类型

Result 类型是 Rust 中最常用的错误处理类型,它表示一个可能出错的操作。Result 类型有两种变体:Ok(T) 和 Err(E)。

使用 Result

use std::fs::File;
use std::io::{self, Read};

fn read_file(filename: &str) -> io::Result<String> {
    let mut file = File::open(filename)?;
    let mut contents = String::new();
    file.read_to_string(&mut contents)?;
    Ok(contents)
}

fn main() {
    match read_file("example.txt") {
        Ok(contents) => println!("File contents: {}", contents),
        Err(e) => eprintln!("Error reading file: {}", e),
    }
}

使用 ? 操作符 ? 操作符用于将 Result 类型的错误向上抛出。

use std::fs::File;
use std::io::{self, Read};

fn read_file(filename: &str) -> io::Result<String> {
    let mut file = File::open(filename)?;
    let mut contents = String::new();
    file.read_to_string(&mut contents)?;
    Ok(contents)
}

fn main() {
    match read_file("example.txt") {
        Ok(contents) => println!("File contents: {}", contents),
        Err(e) => eprintln!("Error reading file: {}", e),
    }
}

Option 类型

Option 类型用于表示可能不存在的值,它有两种变体:Some(T)None

使用 Option

rust
fn find_value(values: &[i32], target: i32) -> Option<i32> {
    for &value in values.iter() {
        if value == target {
            return Some(value);
        }
    }
    None
}

fn main() {
    let numbers = [1, 2, 3, 4, 5];
    match find_value(&numbers, 3) {
        Some(value) => println!("Found value: {}", value),
        None => println!("Value not found"),
    }
}

使用 if let 和 match

fn find_value(values: &[i32], target: i32) -> Option<i32> {
    for &value in values.iter() {
        if value == target {
            return Some(value);
        }
    }
    None
}

fn main() {
    let numbers = [1, 2, 3, 4, 5];
    if let Some(value) = find_value(&numbers, 3) {
        println!("Found value: {}", value);
    } else {
        println!("Value not found");
    }
}

panic! 宏

panic! 宏用于处理不可恢复的错误。当程序遇到不可恢复的错误时,会触发一个 panic,导致程序崩溃。

使用 panic!

fn divide(x: i32, y: i32) {
    if y == 0 {
        panic!("Division by zero");
    }
    println!("Result: {}", x / y);
}

fn main() {
    divide(10, 0);  // 触发 panic!
}

unsafeRust

Unsafe Rust 是 Rust 中的一个重要概念,用于处理那些无法通过 Rust 的类型系统和所有权模型自动验证的操作。常见的 unsafe 操作包括指针操作、内存访问等。

Unsafe 函数和块

// 定义 unsafe 函数
unsafe fn dangerous_operation() {
    // 危险操作
    let mut x = 5;
    let y = &mut x as *mut i32;
    *y = 10;
}

fn safe_function() {
    // 安全函数调用 unsafe 函数
    unsafe {
        dangerous_operation();
    }
}

fn main() {
    safe_function();
}

指针操作

// 定义 unsafe 指针操作
fn pointer_operations() {
    let mut x = 5;
    let y = &mut x as *mut i32;
    unsafe {
        *y = 10;
    }
    println!("x: {}", x);
}

fn main() {
    pointer_operations();
}

不安全的类型转换

// 不安全的类型转换
fn type_casts() {
    let mut x = 5;
    let y: *const i32 = &x;
    unsafe {
        let z: *mut i32 = y as *mut i32;
        *z = 10;
    }
    println!("x: {}", x);
}

fn main() {
    type_casts();
}

macro宏编程

宏是 Rust 中一种强大的元编程工具,用于在编译时生成代码。宏分为两种类型:声明式宏 (macro_rules!) 和过程宏 (proc_macroproc_macro_derive).

声明式宏

macro_rules! my_macro {
    ($val:expr) => {
        println!("Value: {}", $val);
    };
}

fn main() {
    my_macro!(42);
}

过程式宏

过程式宏分为两种:属性宏 (proc_macro_attribute) 和派生宏 (proc_macro_derive)。

属性宏

// 属性宏定义
#[proc_macro_attribute]
pub fn my_attribute(args: TokenStream, input: TokenStream) -> TokenStream {
    // 处理输入
    let args_str = args.to_string();
    let input_str = input.to_string();
    format!("{} [{}] {}", args_str, input_str, "processed").parse().unwrap()
}

// 属性宏使用
#[my_attribute]
struct MyStruct {
    field: i32,
}

fn main() {
    let s = MyStruct { field: 42 };
    println!("MyStruct: {:?}", s);
}

派生宏

// 派生宏定义
#[proc_macro_derive(MyDerive)]
pub fn my_derive(input: TokenStream) -> TokenStream {
    // 处理输入
    let input_str = input.to_string();
    format!("{} [derived] {}", input_str, "processed").parse().unwrap()
}

// 派生宏使用
#[derive(MyDerive)]
struct MyStruct {
    field: i32,
}

fn main() {
    let s = MyStruct { field: 42 };
    println!("MyStruct: {:?}", s);
}

详细示例分析

全局变量示例

// 定义全局变量
static COUNTER: u32 = 0;

fn increment_counter() {
    unsafe {
        COUNTER += 1;
    }
}

fn main() {
    increment_counter();
    println!("Counter: {}", COUNTER);
}

Unsafe 指针操作示例

// 定义 unsafe 指针操作
fn pointer_operations() {
    let mut x = 5;
    let y = &mut x as *mut i32;
    unsafe {
        *y = 10;
    }
    println!("x: {}", x);
}

fn main() {
    pointer_operations();
}

声明式宏示例


macro_rules! my_macro {
    ($val:expr) => {
        println!("Value: {}", $val);
    };
}

fn main() {
    my_ma...

剩余50%的内容订阅专栏后可查看

点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论