Rust 中 i32 与 *i32 的深度解析

Rust 中 &i32*i32 的深度解析

在 Rust 中,&i32*i32 是两种完全不同的指针类型,它们在安全性、所有权和使用方式上有本质区别。以下是详细对比:

核心区别概览

指针类型
引用 &i32
裸指针 *i32
安全
编译器检查
生命周期管理
不安全
手动管理
FFI/底层操作

详细对比分析

1. &i32 - 引用(安全指针)

特性说明
安全性100% 安全,编译器保证有效性
所有权借用检查器控制,不转移所有权
解引用自动解引用(Deref coercion)
使用场景日常 Rust 编程
可变性&i32(不可变)或 &mut i32(可变)
空值永远不为空
别名规则严格遵循借用规则(要么多个不可变引用,要么一个可变引用)
fn safe_ref_example() {let num = 42;let ref_num: &i32 = # // 创建不可变引用// 自动解引用println!("Value: {}", *ref_num); println!("Value: {}", ref_num); // 同样有效// 编译错误:不能同时存在可变和不可变引用// let mut_ref = &mut num;
}

2. *i32 - 裸指针(不安全指针)

特性说明
安全性不安全,需要 unsafe 块操作
所有权无所有权概念,可能悬垂
解引用必须显式解引用(在 unsafe 中)
使用场景FFI、底层系统编程、性能优化
可变性*const i32(不可变)或 *mut i32(可变)
空值可能为空(std::ptr::null()
别名规则无编译时检查,需手动保证安全
fn raw_ptr_example() {let num = 42;let raw_ptr: *const i32 = &num as *const i32;// 必须使用 unsafe 块解引用unsafe {println!("Value: {}", *raw_ptr);}// 可能创建悬垂指针let dangling_ptr: *const i32;{let temp = 100;dangling_ptr = &temp as *const i32;} // temp 离开作用域// 危险:dangling_ptr 现在无效!
}

关键区别详解

1. 安全机制对比

操作
&i32
*i32
编译时检查
借用规则
生命周期验证
运行时风险
悬垂指针
数据竞争

2. 内存访问对比

操作&i32*i32
创建引用/指针&value&value as *const i32
解引用自动或显式 *ref必须 unsafe { *ptr }
空指针不可能std::ptr::null()
指针算术不支持支持(ptr.offset(1)
类型转换有限制(通过 trait)自由转换(as *mut u8

3. 典型使用场景

&i32 场景:
// 函数参数传递
fn print_value(v: &i32) {println!("Value: {}", v);
}// 结构体借用
struct Processor<'a> {data: &'a i32,
}// 迭代器使用
let sum: i32 = vec![1, 2, 3].iter().map(|&x| x * 2).sum();
*i32 场景:
// C 语言交互
extern "C" {fn c_function(ptr: *mut i32);
}// 自定义内存管理
unsafe fn allocate_buffer(size: usize) -> *mut u8 {let layout = std::alloc::Layout::array::<u8>(size).unwrap();std::alloc::alloc(layout)
}// 高性能算法
unsafe fn fast_sum(ptr: *const i32, len: usize) -> i32 {let mut sum = 0;for i in 0..len {sum += *ptr.add(i);}sum
}

转换关系

1. 安全转换

// 引用 → 裸指针(安全)
let num = 42;
let ref_num: &i32 = &num;
let raw_ptr: *const i32 = ref_num as *const i32;

2. 不安全转换

// 裸指针 → 引用(不安全)
unsafe {let ref_back: &i32 = &*raw_ptr;
}

3. 转换注意事项

as *const
unsafe &*
as *const
FFI
Rust调用
安全世界
裸指针
引用
C语言

最佳实践指南

何时使用 &i32

  1. 99% 的日常 Rust 编程
  2. 函数参数传递
  3. 结构体字段借用
  4. 实现 trait 对象 (&dyn Trait)

何时使用 *i32

  1. 与 C 库交互(FFI)
  2. 实现底层数据结构(如自定义分配器)
  3. 极端性能优化场景
  4. 操作系统内核开发

安全使用裸指针的模式:

// 模式1:封装在安全API中
struct SafePointer {ptr: *mut i32,len: usize,
}impl SafePointer {// 安全构造函数pub fn new(data: &mut [i32]) -> Self {SafePointer {ptr: data.as_mut_ptr(),len: data.len(),}}// 安全访问方法pub fn get(&self, index: usize) -> Option<&i32> {if index < self.len {unsafe { Some(&*self.ptr.add(index)) }} else {None}}
}// 模式2:与生命周期绑定
struct GuardedPtr<'a> {ptr: *const i32,_marker: std::marker::PhantomData<&'a i32>,
}impl<'a> GuardedPtr<'a> {pub fn new(reference: &'a i32) -> Self {GuardedPtr {ptr: reference as *const i32,_marker: std::marker::PhantomData,}}pub fn get(&self) -> &'a i32 {unsafe { &*self.ptr }}
}

性能对比

操作&i32*i32
创建开销零成本抽象零成本
解引用开销等同直接访问等同直接访问
安全检查开销编译时(零运行时开销)无检查(需手动验证)
优化潜力编译器充分优化同左,但需更多人工干预

常见错误示例

错误1:悬垂引用

fn dangling_ref() -> &'static i32 {let x = 42;&x // 错误:返回局部变量引用
}

错误2:不安全裸指针使用

fn unsafe_ptr_demo() {let ptr: *const i32;{let value = 100;ptr = &value;} // value 被丢弃unsafe {println!("{}", *ptr); // 未定义行为!}
}

错误3:违反别名规则

fn alias_violation() {let mut data = 42;let ref1 = &data;let ref2 = &mut data; // 错误:同时存在可变和不可变引用println!("{}", ref1);
}

总结对比表

特性&i32*const i32*mut i32
安全性安全不安全不安全
空值不可能可能可能
可变性不可变不可变可变
别名检查严格
生命周期编译器验证无保证无保证
使用场景常规编程FFI/只读访问FFI/写访问
解引用安全unsafeunsafe
自动转换支持 Deref不支持不支持

在 Rust 开发中,优先使用引用 &i32,只有在必要时(如 FFI 或底层系统编程)才使用裸指针 *i32,并且始终将其封装在安全的抽象中。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/93704.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/93704.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【PyTorch项目实战】OpenNMT本地机器翻译框架 —— 支持本地部署和自定义训练

文章目录一、OpenNMT&#xff08;Neural Machine Translation&#xff0c;NMT&#xff09;1. 概述2. 核心特性3. 系统架构4. 与其他翻译工具的区别二、基于 OpenNMT-py 的机器翻译框架1. 环境配置&#xff08;以OpenNMT-py版本为例&#xff09;&#xff08;1&#xff09;pip安装…

基于prompt的生物信息学:多组学分析的新界面

以前总以为综述/评论是假大空&#xff0c;最近在朋友的影响下才发现&#xff0c;大佬的综述/评论内容的确很值得一读&#xff0c;也值得分享的。比如这篇讲我比较感兴趣的AI辅助生信分析的&#xff0c;相信大家都是已经实践中用上了&#xff0c;看看大佬的评论&#xff0c;拓宽…

Nacos-8--分析一下nacos中的AP和CP模式

Nacos支持两种模式来满足不同场景下的需求&#xff1a;AP模式&#xff08;强调可用性&#xff09;和CP模式&#xff08;强调一致性&#xff09;。 这两种模式的选择主要基于CAP理论&#xff0c;该理论指出在一个分布式系统中&#xff0c;无法同时保证一致性&#xff08;Consist…

水闸安全监测的主要核心内容

水闸安全监测是指通过一系列技术手段和管理措施&#xff0c;对水闸的结构状态、运行性能及环境条件进行实时或定期的观测与评估&#xff0c;以确保水闸在设计寿命期内的安全性和可靠性。其核心目标是及时发现潜在的安全隐患&#xff0c;防止事故发生&#xff0c;保障水利工程的…

嵌入式系统学习Day19(数据结构)

数据结构的概念&#xff1a; 相互之间存在一种或多种特定关系的数据元素的集合。数据之间关系&#xff1a;逻辑关系&#xff1a;集合&#xff0c;线性&#xff08;1对1&#xff0c;中间位置的值有且仅有一个前驱&#xff0c;一个后继&#xff09;&#xff0c;树&#xff08;1对…

Pandas中数据清理、连接数据以及合并多个数据集的方法

一、简介1.数据清理的重要性&#xff1a;在进行数据分析前&#xff0c;需进行数据清理&#xff0c;使每个观测值成一行、每个变量成一列、每种观测单元构成一张表格。2.数据组合的必要性&#xff1a;数据整理好后&#xff0c;可能需要将多张表格组合才能进行某些分析&#xff0…

JavaSSM框架从入门到精通!第二天(MyBatis(一))!

一、 Mybatis 框架1. Mybatis 框架简介Mybatis 是 apache 的一个开源项目&#xff0c;名叫 iBatis &#xff0c;2010 年这个项目由 apache 迁移到了 google&#xff0c;并命名为 Mybatis&#xff0c;2013 年迁移到了 GitHub&#xff0c;可以在 GitHub 下载源码。2. Mybatis 的下…

Linux下Mysql命令,创建mysql,删除mysql

在 Linux 系统下&#xff0c;您可以通过命令行来创建和删除 MySQL 数据库。以下是详细的操作步骤&#xff0c;包括创建和删除数据库、用户&#xff0c;以及常见的相关管理命令。1. 登录 MySQL在执行任何 MySQL 操作之前&#xff0c;需要先登录 MySQL。1.1 使用 root 用户登录 M…

假设检验的原理

假设检验是统计学中用于判断样本数据是否支持某个特定假设的方法。其核心思想是通过样本数据对总体参数或分布提出假设&#xff0c;并利用统计量来判断这些假设的合理性。假设检验的基本步骤如下&#xff1a;1. 假设&#xff08;Hypothesis&#xff09;在统计学中&#xff0c;假…

信号、内存共享等实现

信号&#xff08;signal&#xff09;#include <signal.h> #include <stdio.h> #include <unistd.h>void handler(int sig) {printf("收到信号: %d\n", sig); }int main() {signal(SIGUSR1, handler); // 注册用户自定义信号printf("进程 PI…

《从日常到前沿:AI 在教育、医疗、制造业的真实落地案例》文章提纲

引言&#xff1a;AI 落地的多元图景​简述 AI 从实验室走向实际应用的发展趋势​说明选择教育、医疗、制造业的原因 —— 覆盖民生与基础产业&#xff0c;落地场景具有代表性​AI 在教育领域的落地案例​个性化学习&#xff1a;如某在线教育平台利用 AI 分析学生学习数据&#…

决策树(1)

一、树模型与决策树基础决策树概念&#xff1a;从根节点开始一步步走到叶子节点得出决策&#xff0c;所有数据最终都会落到叶子节点&#xff0c;既可用于分类&#xff0c;也可用于回归。树的组成根节点&#xff1a;第一个选择点。非叶子节点与分支&#xff1a;中间决策过程。叶…

电视系统:开启视听新时代

在当今数字化浪潮席卷的时代&#xff0c;电视领域正经历着一场深刻的变革&#xff0c;而电视系统无疑是这场变革中的耀眼明星。简单来讲&#xff0c;电视系统就是互联网协议电视&#xff0c;它宛如一座桥梁&#xff0c;巧妙地利用宽带有线电视网&#xff0c;将多媒体、互联网、…

字节开源了一款具备长期记忆能力的多模态智能体:M3-Agent

猫头虎AI分享&#xff5c;字节开源了一款具备长期记忆能力的多模态智能体&#xff1a;M3-Agent 近年来&#xff0c;多模态大模型的发展迅猛&#xff0c;但如何赋予智能体类似人类的长期记忆能力&#xff0c;一直是研究中的核心挑战。字节跳动开源的 M3-Agent&#xff0c;正是面…

第十六届蓝桥杯青少组C++省赛[2025.8.10]第二部分编程题(6、魔术扑克牌排列)

参考程序&#xff1a;#include<bits/stdc.h> using namespace std; long long dp[105]; long long c(int n) {dp[0] 1;for(int i1; i< n; i){for(int j0; j<i; j){dp[i] dp[j] * dp[i -1-j];}}return dp[n]; } int main() {int n;cin >> n;cout <<c(n…

【实时Linux实战系列】实时平台下的图像识别技术

在当今数字化时代&#xff0c;图像识别技术已经广泛应用于各个领域&#xff0c;如自动驾驶、安防监控、智能医疗等。它通过计算机对图像进行分析和处理&#xff0c;从而实现对物体、场景或人的识别。实时Linux作为一种高效的实时操作系统&#xff0c;为图像识别技术提供了强大的…

IPD流程执行检查表

IPD流程执行检查表 稽查

Jmeter的安装与使用教程

基于jdk1.8版本的Jmeter的下载与安装和使用教程。 一.安装jmeter 官网下载就行下载压缩包解压就行 Jmeter下载官网&#xff1a;http://jmeter.apache.org/download_jmeter.cgi找到安装包的下载位置&#xff0c;解压进入文件夹的bin文件夹下jmeter.bat。二.配置环境变量 1、“此…

docker 数据卷、自定义镜像操作演示分享(第二期)

数据卷1.1、背景前面有个docker go web demo应用示例&#xff0c;每次为了部署go_web_demo工程&#xff0c; 需要将使用到的cp的命令将宿主主机内的go_web_demo目录下的代码文件&#xff08;一般是编译后的二进制执行文件&#xff09;复制到容器内部。 数据卷&#xff1a;将宿主…

Pandas 入门到实践:核心数据结构与基础操作全解析(Day1 学习笔记)

目录 一、Pandas 概述 1. 什么是 Pandas 二、核心数据结构 1. Series 索引 显示索引 隐式索引 创建方式 属性与方法 数据访问 索引访问 切片访问 布尔索引 2. DataFrame 创建方式 属性与数据访问 数据修改 三、索引操作 1. 索引类型 2. 核心索引方法 3. 切…