[易學易懂系列|rustlang語言|零基礎|快速入門|(3)|所有權Ownership]


今天我們來講講rust最難,也是最重要的概念:

Ownership,Borrowing,Lifetimes

首先我們來看看:ownership(所有權)

我們來看看下面的代碼:

let a = [1, 2, 3];

let b = a;

println!("{:?} {:?}", a, b); // [1, 2, 3] [1, 2, 3]


let a = vec![1, 2, 3];

let b = a;

println!("{:?} {:?}", a, b); // Error; use of moved value: a


我們把這兩段代碼,放在vscode里去build.

第一段代碼沒有問題,第二段代碼報錯。

vscode會報錯信息:

  println!("{:?} {:?}", a, b); // Error; use of moved value: `a`
|                       ^ value borrowed here after move

編譯器已經告訴我們原因:value borrowed here after move

也就是說a對原來數據的所有權已經move(移動)給b,這時再訪問a的值。編譯器就會報告你犯了一個嚴重錯誤。

我們用簡單的圖示來說明:

如圖,a原來有本書,現在給了b.

 

那現在,這本書就在b手上了。b擁有這本書。

對應代碼就是:

let a = vec![1, 2, 3];

let b = a;// a把數據給b.

那這個時候,a已經沒有對數據的所有權,就訪問不了數據,編譯器就報錯。

那為什么第一段代碼,又不報錯呢?

原來,rust中分兩種數據類型:

1.基本數據類型: 如:bool(布爾),char(字符),integer(整數),floating(浮點),arrays(數組),tuples(元組),slice(切片),字符串(str),函數指針(functions)

對基本類型的詳細說明 可以參考英文教程:

https://learning-rust.github.io/docs/a6.variable_bindings,constants_and_statics.html

或中文參考:http://wiki.jikexueyuan.com/project/rust/primitive-types.html

2.非基本類型:

即除基本類型外的其它類型,一般為引用類型。

那rust對這兩種類型會分別不同處理:

對基本類型,rust會對原來a的數據復制,並把復制數據賦值給b,並把原始數據的所有權狀態 設置為“已復制( copied )”狀態。

對非基本類型,rust會把原來a的數據移動,並把原始數據賦值給b,並把原始數據的所有權狀態 設置為“已移動( moved )”狀態。

針對這兩種處理模式,rust內部又定義為兩種類型:復制類型(Copy type ),移動類型( Move type

但這里還要注意一點,對於函數指針類型,一般情況下為移動類型( Move type ),但如果它實現以下接口:

core::marker::Copy trait

 則它也是復制類型,執行復制的模式。

以上,就是所有權的基本概念和要點。

其實,我們重新思考多線程中的數據安全,rust的這種設計,是非常合理的。

(關於線程安全的問題,我之前寫過java的高並發與鎖的原理系列,見:https://www.cnblogs.com/gyc567/p/11014782.html

首先,rust定義數據初始化動作為綁定,並且默認為不可變,如下:

let a =9;

a=10;//error

第二行代碼 a=10;是會報錯的。為什么?因為它是不可變的,如果要改變,就要把它定義為mut(可變),如下:

let mut a =9;

a=10;//correct

所以,rust的設計哲學就是默認所有線程操作都是不安全的。那所有數據默認為不可變,在多線程環境下,就是相當於所有線程都可以共享數據,是線程安全的,因為數據是不變的。

那回到上面的所有權的概念,復制類型(Copy type )就相當於數據共享,可以共享復制數據,但禁止寫。移動類型( Move type )就相當於獨占鎖,線程擁有這把“鎖”,才能訪問數據,否則報錯。

以上,希望對你有用。

如果遇到什么問題,歡迎加入:rust新手群,在這里我可以提供一些簡單的幫助,加微信:360369487,注明:博客園+rust


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM