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
英文地址,請注明出處:http://en.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. 切…