偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

初識Rust語言的所有權(quán)概念

移動開發(fā) 開發(fā)
初步探索火狐的東家Mozilla的新語言rust的所有權(quán)和借用概念,看看怎么在編譯期解決并發(fā)問題的。

目前僅看了第二版的官方文檔,記錄一下初步印象,應(yīng)該還有更深刻一致的解釋,水平有限,僅供參考。
實驗環(huán)境:ubuntu17.10,rust1.18,vscode1.14 + 擴展rust(rls)。
BTW,環(huán)境搭建順利得令人意外,Rust工具鏈打造的簡潔精美,原生支持git,安裝只需一條命令:curl https://sh.rustup.rs -sSf | sh。

初步印象

數(shù)據(jù)競爭主要有三個條件:

  1. 兩個或更多指針同時訪問同⼀數(shù)據(jù)。
  2. ⾄少有⼀個指針被寫⼊。
  3. 沒有同步數(shù)據(jù)訪問的機制。

R非常重視并發(fā),根據(jù)官方介紹:Rust 是一門著眼于安全、速度和并發(fā)的編程語言。而并發(fā)需要解決的就是數(shù)據(jù)競爭問題,自然會非常重視數(shù)據(jù)的使用過程,說是小心翼翼不為過。因為數(shù)據(jù)要關(guān)聯(lián)到有名變量才能使用,所以rust在語言層面上針對變量的使用引入了解決方法,主要涉及的語法有:

  1. 變量聲明時,不可變(immutable,默認)、可變(mutable)
  2. 變量賦值時,所有權(quán)轉(zhuǎn)移(move)、借用(borrow)

需要注意的是,所有權(quán)僅針對復雜類型變量(在語法上,是沒有copy trait的類型),例如String、vect等在堆上存儲數(shù)據(jù)的類型,而簡單類型并不用考慮,如int、tuple、array等,原因就在于賦值時數(shù)據(jù)是如何拷貝的(雖然都是淺拷貝)。

如果熟悉淺拷貝、深拷貝的概念,自然了解,對于在堆上分配空間的復雜類型,淺拷貝會導致兩個或更多變量/指針同時指向同⼀數(shù)據(jù),若有變量/指針作寫入操作,就會引起數(shù)據(jù)競爭問題。 

首圖

所以,Rust用可變/不可變、所有權(quán)、生命期等來破壞數(shù)據(jù)競爭的條件,而這些解決方案全部在編譯期搞定!
當然,代價是難以快速驗證想法,畢竟使用變量時要仔細了,否則編都編不過,期待***實踐和IDE的支持。

基本概念

1. 不可變、可變

let x = 3;  // x 默認不可變
x = 4;  // 錯誤!
let x = 4;  // 正確!遮蓋了原有的同名變量
let mut y = 3;  // y可變
y = 4;  // 正確!

2. 所有權(quán)轉(zhuǎn)移(move)

fn test(v: String) { println!("fn: {}", v); }  // 函數(shù)
let x = String::from("hello");  // 所有者x(String類型)
let y = x;  // 數(shù)據(jù)的所有權(quán)轉(zhuǎn)移給y!
let z = x; // 錯誤!x已不可用
test(y);  // 所有權(quán)轉(zhuǎn)移,新的所有者是形參v!當函數(shù)執(zhí)行完畢,v離開作用域時值被丟棄(drop)!
println!("var: {}", y);  // 錯誤!y已不可用

這難免有令人抓狂的感覺,還能不能愉快地玩耍了?這數(shù)據(jù)跑得跟兔子一樣,想用的時候都不知道去哪了!還可能無意中跑到函數(shù)里直接躺尸!

3. 借用/引用(borrow)

那么,一個變量想多次使用怎么辦?答案是可以借用:使⽤其值但不獲取其所有權(quán)。

fn test1(v: String) { println!("fn: {}", v); } 
fn test2(v: &String) { println!("fn: {}", v); }  // 參數(shù)為引用類型
let s = String::from("hello");  // 所有者s(String類型)
let s1 = &s;  // 不可變借用(borrow)!
let s2 = &s;  // 借用
let s3 = s1;  // 借用
test2(s1);  // 借用
test1(*s1);  // 錯誤!借用者s1沒有所有權(quán),無法通過s1轉(zhuǎn)移(cannot move out of borrowed content)。
println!("var: {}", s); // 正確

小結(jié):個人感覺,所有權(quán)轉(zhuǎn)移主要為并發(fā)服務(wù),本身并不常用,畢竟數(shù)據(jù)經(jīng)常要復用,沒人樂意要一直提防著數(shù)據(jù)跑哪去了,尤其在函數(shù)調(diào)用時。既然如此,一般把所有者保持不變,多使用引用,主要體現(xiàn)在復雜數(shù)據(jù)結(jié)構(gòu)和函數(shù)上。

進一步

但是,實際使用的情況會比較復雜,即是否可變與轉(zhuǎn)移、借用三者相互影響(混用)的情況。
從數(shù)據(jù)競爭的角度:讀讀不沖突,但讀寫、寫寫會沖突(讀即不可變,寫即可變);從實現(xiàn)的角度:引用是基于所有權(quán)的。
因此,可以看看哪些對象會沖突:(所有者,引用) × (不可變,可變) 

首先,是否可變和所有權(quán)沒有關(guān)系。

let x = String::from("hello");
let mut z = x;  // 轉(zhuǎn)移后變量x不可用
z.push_str(" z");  //正確
// 可變引用要用星號來獲得引用的內(nèi)容,不可變引用不需要。
let mut x = 5; 
let y = &mut x;
*y += 1;

 

雖然不可變引用(&T)沒有所有權(quán),不會導致值被誤轉(zhuǎn)移,但借用之時要求值不能變,這意味著此時:所有權(quán)不能轉(zhuǎn)移、所有者不能改值、不能同時有可變引用!

let mut x = String::from("hello");
let y = &x;  // 不可變引用
let z = x;  // 錯誤
x.push_str(" x");  // 錯誤
let z = &mut x;  // 錯誤:可變引用

 

可變引用(&mut T)

可變引用使用上略復雜,概念上也沒有太統(tǒng)一的理解,這里單獨考查。
“可變權(quán)”即可變引用對數(shù)據(jù)的讀寫權(quán),具有唯一性(只有一個可用的可變引用)和獨占性(其它讀、寫統(tǒng)統(tǒng)無效),所以對編譯影響相當大。可變引用的可變權(quán)和所有者對數(shù)據(jù)的所有權(quán)有相似性,因為可變權(quán)也有move行為。

注:官方文檔里沒有可變權(quán)的概念,但個人感覺,用這個概念比較好理解可變引用的使用,也許還有更本質(zhì)的解釋,特此說明。

可變權(quán)move的兩種方式

let mut x = String::from("hello");  // 所有者x有可變權(quán)
// 1. 直接轉(zhuǎn)移
let y = &mut x;  // 1. y為可變引用,可變權(quán)move自x
let z = y;  // 直接轉(zhuǎn)移。z為可變引用
y.push_str(" y");  // 錯誤!y的可變權(quán)已move給z
z.push_str(" z");  // 正確
// 2. 間接轉(zhuǎn)移
let mut y = &mut x;  // 2. y為可變引用,可變權(quán)move自x
let w = &mut y;  // 要求y可變。w為可變引用
w.push_str(" w");  // 正確
// 轉(zhuǎn)移(函數(shù))
fn test(i: &mut String) { 
  i.push_str(" i");   // 正確
}
let mut x = String::from("hello");  // 所有者x有可變權(quán)
test(&mut x);
x.push_str(" x");  // 正確!可變權(quán)已歸還

 

可變引用若有寫入操作則要求所有者可變。

let x = String::from("hello");  // x不可變
let mut z = &x;   // z為不可變引用
z.push_str(" z");  // 錯誤!
let w = &mut z;  // w為可變引用
w.push_str(" w");  // 錯誤!
let mut y = x;  // 所有權(quán)轉(zhuǎn)移,y可變
let z = &mut y;   // z為可變引用,要求y可變
z.push_str(" z");  // 正確!
let w = &z;  // w 為不可變引用
w.push_str(" w");  // 錯誤!

 

總結(jié):

因為都涉及到值的修改,可變引用的行為和所有者相似,而且可變權(quán)和所有權(quán)都是面向數(shù)據(jù)且唯一的。

所有者

  1. 有所有權(quán),move后不再可用,當所有者生命期結(jié)束,值被丟棄。
  2. 讀的時候類似不可變引用,寫的時候類似可變引用。

可變引用(&mut T)

  1. 有可變權(quán),move自被引用者,當可變引用生命期結(jié)束,可變權(quán)自動歸還。
  2. 可變權(quán)的源頭應(yīng)該來自所有者,否則意義不大。

參考

  1. Rust 環(huán)境配置事項一覽
  2. 官方文檔:Rust 程序設(shè)計語言(第二版)
  3. Rust教程11之所有權(quán)
  4. 你在開發(fā)過程中都遇到過 Rust 的哪些坑?
責任編輯:張子龍 來源: 開源中國社區(qū)
相關(guān)推薦

2024-03-19 14:43:55

Rust編譯所有權(quán)

2024-01-10 09:26:52

Rust所有權(quán)編程

2022-08-11 10:42:58

Rust

2024-09-02 10:40:18

2024-04-24 12:41:10

Rust安全性內(nèi)存

2022-03-18 08:00:00

區(qū)塊鏈代幣以太坊

2011-01-07 09:19:35

Linux文件權(quán)限

2021-07-30 05:12:54

智能指針C++編程語言

2013-08-16 10:46:20

2022-05-30 00:19:13

元宇宙NFTWeb3

2022-11-03 15:14:43

Linux文件權(quán)限

2018-01-23 11:15:28

云計算數(shù)據(jù)平臺云平臺

2011-01-20 07:50:51

Linux文件系統(tǒng)管理所有權(quán)

2009-11-28 20:21:14

2018-12-14 10:08:23

物聯(lián)網(wǎng)訂閱IOT

2009-09-12 09:46:47

Windows 7所有權(quán)添加

2017-10-23 12:42:42

2020-09-09 09:19:00

SpringSecurity權(quán)限

2010-07-20 17:36:55

SQL Server

2013-06-14 10:34:34

iOS App蘋果iOS開發(fā)者
點贊
收藏

51CTO技術(shù)棧公眾號