日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

Rust你不認識的所有權_Rust語言

作者:全年無休的IT老兵 ? 更新時間: 2023-03-25 編程語言

在Rust中是沒有內存垃圾回收機制(GC)的,那Rust是如何保障內存安全的呢?這就引出了“所有權”這個概念。

我們看下下面這段偽代碼

let s = "helloString";
t = s;
print(s);

在之前我們學習的語言中,比如C語言,對于上述偽代碼的執行結果應該是正常打印"helloString" 的內容,但是在Rust中,執行上述代碼時,會出現如下提示

------ 增加所有權返回內容;

而產生這個結果的原因就是觸發了Rust語言中所有權機制:

  • Rust中的每一個值都有一個對應的變量作為它的所有者
  • 在同一時間內,值有且僅有一個所有者
  • 當所有者離開自己的作用域時,它持有的值就會被釋放掉

在看這三條機制之前,需要先說明一下Rust中變量作用域的概念

作用域:一個對象在程序中有效的范圍。

比如如下Rust代碼

{
    let s = "hello";
}

在花括號內部就是變量s的作用域,當源碼超出這個范圍后,變量s將不再可用,即

{
    let s = "hello";
}
println!("{}", s);

打印這一句代碼編譯時會報錯。因為在Rust語言中,當變量離開作用域時Rust會自動調用變量的"drop"函數,以此保障內存的快速回收。上述源碼中,在代碼執行到“}”時,Rust調用了變量s的drop函數,所以s指向的內存失效,從而導致在執行打印語句時會出錯,也就是這個邏輯保障了Rust語言中內存的安全性。

我們再說回文章開頭的偽代碼例子,為什么編譯時會出現問題,這里我們就要詳細介紹一下這些語句在Rust中的邏輯。

let s = "helloString";

這句語句是聲明了一個變量并使用“helloString”進行了初始化

簡化展示,隱藏內部詳細邏輯

t = s;

這個語句是將變量s的內容同時賦值給變量t,如下圖,如果每次賦值的時候都全量內存拷貝一份的話,那整體語言性能會下降很多(畢竟變量地址大小還是不可確定的),所以處理方式是新建一個變量t,然后將內容內存指向s的指向地址。

上述情況下就出現了一個情況,同一個值被兩個變量所指向,這個不符合Rust所有權的規則,所以Rust根據所有權做了一個語言限制,即當s賦值給新的變量t時,變量t指向s指向的內容,而變量s本身將被Rust擦除,所以在執行完賦值語句后,等號右側(也就是s)將無效,在Rust語言中將這個行為叫做變量的移動,從字面意思理解也就是將變量s所有的值移動到變量t中,移動完成后s的生命周期也隨之結束。

Rust有了移動這個概念,那對于其他語言中的深度拷貝或再次賦值的情況下Rust中該如何做呢?為了解決這個問題,Rust提出了另外一個變量與數據的交互方式——克隆,意思就是將s的數據完整的克隆一份給t,s的內容不變:

以Rust字符串數據結構為例子,可參考如下:

let s1 = String::from("hello");
let s2 = s1.clone();  // 此處為克隆的默認方法
println!("s1={}, s2={}", s1, s2); 

從執行結果可以看出,克隆后s1變量內容不變,還可以繼續使用。

上述就是Rust所有權的一些學習心得。

原文鏈接:https://blog.csdn.net/minibrid/article/details/128775276

欄目分類
最近更新