任何事情都是相對的,就像rust給我們的印象一直是安全、快速,但實際上,完全的安全是不可能實現的。因此,rust中也是會有不安全的**的。
嚴格來講,rust語言可以分為safe rust和unsafe rust。unsafe rust是safe rust的超集。在unsafe rust中並不會禁用任何的安全檢查,unsafe rust出現的原因是為了讓開發者可以做一些更加底層的操作。這些事情本身也是不安全的,如果仍然要進行rust的安全檢查,那麼就無法進行這些操作。
在進行下面這5種操作時,unsafe rust不會進行安全檢查。
解引用原生指標
呼叫unsafe的函式或方法
訪問或修改可變的靜態變數
實現unsafe的trait
讀寫聯合體中的字段
基礎語法
unsafe rust的關鍵字是unsafe,它可以用來修飾函式、方法和trait,也可以用來標記**塊。
標準庫中也有不少函式是unsafe的。例如string中的from_utf8_unchecked()函式。它的定義如下:
pub unsafe fn from_utf8_unchecked(bytes: vec) -> string
這個函式被標記為unsafe的原因是函式並沒有檢查傳入引數是否是合法的utf-8序列。也就是提醒使用者注意,使用這個函式要自己保證引數的合法性。
用unsafe標記的trait也比較常見,在前面我們見過的send和sync都是unsafe的trait。它們被用來保證執行緒安全, 將其標記為unsafe是告訴開發者,如果自己實現這兩個trait,那麼**就會有安全風險。
我們在呼叫unsafe函式或方法時,需要使用unsafe**塊。
fn main() ", *r1);
println!("r2 is: {}", *r2);
在rust程式設計中,原生指標常被用作和c語言打交道,原生指標有一些特有的方法,例如可以用is_null()來判斷原生指標是否是空指標,用offset()來獲取指定偏移量的記憶體位址的內容,使用read()/write()方法來讀寫記憶體等。
呼叫unsafe的函式或方法
呼叫unsafe的函式或方法必須放到unsafe**塊中,這點我們在基礎知識中已經介紹過。因為函式本身被標記為unsafe,也就意味著呼叫它可能存在風險。這點無需贅述。
訪問或修改可變的靜態變數
對於不可變的靜態變數,我們訪問它不會存在任何安全問題,但是對於可變的靜態變數而言,如果我們在多執行緒中都訪問同乙個變數,那麼就會造成資料競爭。這當然也是一種不安全的操作。所以要放到unsafe**塊中,此時執行緒安全應由開發者自己來保證。
static mut counter: u32 = 0;
fn add_to_count(inc: u32) ", counter);
在這個例子中我們沒有使用多執行緒,這裡只是想展示一下如何訪問和修改可變靜態變數。
實現unsafe的trait
當trait中包含乙個或多個編譯器無法驗證其安全性的方法時,這個trait就必須被標記為unsafe。而想要實現unsafe的trait,首先在實現**塊的關鍵字impl前也要加上unsafe標記。其次,無法被編譯器驗證安全性的方法,其安全性必須由開發者自己來保證。
前面我們也提到了,常見的unsafe的trait有send和sync這兩個。
讀寫聯合體中的字段
rust中的union聯合體和enum相似。我們可以使用union關鍵字來定義乙個聯合體。
union myunion ;
unsafe ", my_union.i);
在初始化時,我們每次只能指定乙個欄位的值。這就造成我們在訪問聯合體中的字段時,有可能會訪問到未定義的字段。因此,rust讓我們把訪問操作放到unsafe**塊中,以此來警示我們必須自己保證程式的安全性。
總結本文我們聊了unsafe rust的一些使用場景和使用方法。你只需要記住unsafe的5種操作就好,在遇到這些操作時,一定要使用unsafe**塊。unsafe**塊不光是為了「騙」過編譯器,要時刻提醒自己,unsafe**塊中的程式要由開發者自己保證其正確性。
解引用原生指標
呼叫unsafe的函式或方法
訪問或修改可變的靜態變數
實現unsafe的trait
讀寫聯合體中的字段
rust整理筆記 rust基本操作 01
1.安裝 1.1 rust mac安裝 curl ssf shsource home cargo env1.2.顯示rustc版本 rustc version 注 如果顯示版本號 提交的 hash 值和提交時間,恭喜你!則 rust 已成功安裝!1.3.顯示cargo cargo version如果...
rust腐竹是什麼意思 Rust
rust 資料型別 rust 語言中的基礎資料型別有以下幾種。整數型 integer 整數型簡稱整型,按照位元位長度和有無符號分為一下種類 位長度有符號 無符號8 bit i8u8 16 bit i16u16 32 bit i32u32 64 bit i64u64 128 bit i128 u128...
rust 案例 元組 通過例子學 Rust
元組 元組是乙個可以包含各種型別的組合。元組使用括號 來構成,每個元組的值都是 t1,t2,型別標記的形式,其中 t1,t2 是每個元素的型別。函式可以使用元組來返回多個值,因為元組可以 擁有任意數量的值。元組可以充當函式的引數和返回值 fn reverse pair i32,bool bool,i...