当前位置: 首页 > news >正文

Rust unsafe

概述

Rust 中的 unsafe 关键字 用于标记哪些编译器无法完全验证安全性的代码。它允许你执行一些通常被 Rust 的安全规则禁止的操作,但同时要求程序员自己确保这些操作的安全性

什么是 unsafe ?

unsafe 不意味着代码一定危险,而是意味着:

  1. 编译器无法自动验证这段代码的内存安全性
  2. 程序员需要手动确保代码符合Rust 的安全约定
  3. 允许访问一些通常被禁止的低级功能

例子

unsafe 允许的五大操作

  • 解引用裸指针
  • 调用不安全函数
  • 访问和修改可变静态变量
  • 实现不安全 trait
  • 访问联合体字段

解引用裸指针

Unsafe: 直接通过裸指针读取或写入数据

fn unsafe_raw_pointer() {let x = 10;let y = 20;// 创建裸指针是安全的let raw_ptr1 = &x as *const i32;let raw_ptr2 = &y as *const i32;unsafe {// 解引用裸指针需要 unsafelet value1 = *raw_ptr1;let value2 = *raw_ptr2;println!("Unsafe: {} + {} = {}", value1, value2, value1 + value2);}
}

safe: 使用引用(&和&mut),由编译器检查生命周期和借用规则

fn safe_references() {let x = 10;let y = 20;// 使用引用,编译器会验证安全性let ref1 = &x;let ref2 = &y;// 直接解引用,编译器保证安全let value1 = *ref1;let value2 = *ref2;println!("Safe: {} + {} = {}", value1, value2, value1 + value2);// 或者更简洁的方式println!("Safe simpler: {} + {} = {}", x, y, x + y);
}

调用不安全函数

unsafe: 调用被标记为unsafe的函数

// 声明不安全函数
unsafe fn dangerous_function(buffer: *mut [u8; 1024]) {if !buffer.is_null() {// 直接操作内存(*buffer)[0] = 42;}
}fn call_unsafe() {let mut data = [0u8; 1024];unsafe {dangerous_function(&mut data as *mut [u8; 1024]);}println!("Unsafe result: {}", data[0]);
}

safe: 调用safe函数,或者通过安全封装后的函数(内部可能包含unsafe,但对外是safe的接口)

// 安全函数声明
fn safe_function(buffer: &mut [u8; 1024]) {// 使用安全的索引访问buffer[0] = 42;
}fn call_safe() {let mut data = [0u8; 1024];// 直接调用,无需 unsafesafe_function(&mut data);println!("Safe result: {}", data[0]);
}

访问和修改可变静态变量

unsafe: 直接读写可变静态变量(static mut)

static mut GLOBAL_COUNTER: u32 = 0;fn unsafe_global_modification() {unsafe {GLOBAL_COUNTER += 1;println!("Unsafe global: {}", GLOBAL_COUNTER);}
}

safe: 使用原子类型或者通过Mutex等同步机制来安全地共享可变状态

use std::sync::atomic::{AtomicU32, Ordering};
use std::sync::Mutex;// 使用原子操作
static SAFE_COUNTER: AtomicU32 = AtomicU32::new(0);// 或者使用互斥锁
static SAFE_DATA: Mutex<Vec<String>> = Mutex::new(Vec::new());fn safe_global_modification() {// 原子操作 - 线程安全且无需 unsafelet count = SAFE_COUNTER.fetch_add(1, Ordering::SeqCst);println!("Safe atomic: {}", count + 1);// 互斥锁保护 - 线程安全{let mut data = SAFE_DATA.lock().unwrap();data.push("hello".to_string());}
}

实现不安全trait

unsafe: 实现一个被标记为unsafe的trait

// 不安全 trait,实现者必须保证某些不变量
unsafe trait UnsafeSend: Send {// 实现者必须保证这个类型可以安全地跨线程发送
}unsafe impl UnsafeSend for i32 {// 我们知道 i32 可以安全发送
}struct MyUnsafeType {data: *mut u8,
}unsafe impl Send for MyUnsafeType {// 手动保证这个类型可以安全发送
}

safe: 实现普通的trait。

// 安全 trait,编译器会自动验证安全性
trait SafeTrait {fn do_something(&self);
}// 自动推导的 trait 实现
#[derive(Clone, Debug)]
struct MySafeType {data: Vec<u8>,
}impl SafeTrait for MySafeType {fn do_something(&self) {println!("Safe trait implementation");}
}// 自动实现 Send 和 Sync(因为所有字段都实现了这些 trait)
// 编译器自动验证,无需手动保证

访问联合体字段

unsafe: 访问Rust联合体(union)的字段

#[repr(C)]
union MyUnion {integer: u32,float: f32,bytes: [u8; 4],
}fn unsafe_union_access() {let u = MyUnion { integer: 0x40490FDB }; // PI 的 IEEE 754 表示unsafe {// 访问联合体字段需要 unsafeprintln!("Unsafe union - as integer: {}", u.integer);println!("Unsafe union - as float: {}", u.float);println!("Unsafe union - as bytes: {:?}", u.bytes);}
}

safe: 使用枚举(enum)或者结构体(struct)来避免直接访问联合体

// 使用枚举替代联合体
enum SafeVariant {Integer(u32),Float(f32),Bytes([u8; 4]),
}impl SafeVariant {fn as_integer(&self) -> Option<u32> {match self {SafeVariant::Integer(i) => Some(*i),_ => None,}}fn as_float(&self) -> Option<f32> {match self {SafeVariant::Float(f) => Some(*f),_ => None,}}fn as_bytes(&self) -> Option<[u8; 4]> {match self {SafeVariant::Bytes(b) => Some(*b),_ => None,}}
}fn safe_enum_access() {let variant = SafeVariant::Integer(0x40490FDB);// 安全访问,类型安全if let Some(int_val) = variant.as_integer() {println!("Safe enum - as integer: {}", int_val);}// 或者使用模式匹配match variant {SafeVariant::Integer(i) => println!("Matched integer: {}", i),SafeVariant::Float(f) => println!("Matched float: {}", f),SafeVariant::Bytes(b) => println!("Matched bytes: {:?}", b),}
}
http://www.dtcms.com/a/503234.html

相关文章:

  • 辽宁省建设工程造价管理协会网站wordpress登陆按钮
  • 【pulldown-cmark】 初学者指南
  • [嵌入式系统-140]:Android以及其衍射版本都是基于Linux,Ubuntu、Rehat也都是基于Linux,异同进行比较。
  • GitLab 代码基础操作清单
  • 深度学习经典分类(算法分析与案例)
  • 做网站的叫什么百度seo引流怎么做
  • js,后端,css记录
  • 云服务器部署Python后端偶遇`ImportError`: 从依赖版本到Python升级的排错全攻略
  • 使用AI编程工具的“经济学”:成本控制与性能优化策略
  • 免费网站收录运营一个app大概多少钱
  • void编辑器+mcpsever本地demo部署
  • 企业做网站设计页面图片
  • S7500 连续波可调谐激光器的控制
  • Blossom插件的使用
  • 做网站知识点做家教网站挣钱吗
  • AWS云基础设施可观测性完整指南
  • MySQL 常用函数实操指南:从基础到实战案例
  • FastAPI(一)——路径操作
  • 达梦数据库备份与恢复:dexp 和 dimp 工具的使用与优化
  • 众划算网站开发网站建设与管理教案怎么写
  • Agent 开发设计模式(Agentic Design Patterns )第 7 章:多智能体协作(Multi-Agent Collaboration)
  • LangGraph React智能体 - 推理与行动的完美结合
  • `tanslate=“no“`避免使用 HTML 中的翻译属性自动翻译品牌名称等
  • 深圳led网站建设最好的手表网站
  • Oracle 常见的33个等待事件
  • 比特位计数(二)
  • Linux网络HTTP(中)(8)
  • wordpress老站开启多站点wordpress评论是关闭还是开启
  • 建设宣传网站上的请示邯郸网站建设哪能做
  • Linux 例行性工作任务(定时任务)知识点总结