国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Rust核心功能之一(所有權(quán))

這篇具有很好參考價(jià)值的文章主要介紹了Rust核心功能之一(所有權(quán))。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

目錄

1、什么是所有權(quán)?

1.1?所有權(quán)規(guī)則

?1.2 變量作用域

1.3 String 類型

1.4 內(nèi)存與分配

變量與數(shù)據(jù)交互的方式(一):移動(dòng)

變量與數(shù)據(jù)交互的方式(二):克隆

只在棧上的數(shù)據(jù):拷貝

1.5 所有權(quán)與函數(shù)

1.6 返回值與作用域


1、什么是所有權(quán)?

所有權(quán)(系統(tǒng))是 Rust 最為與眾不同的特性,對(duì)語(yǔ)言的其他部分有著深刻含義。它讓 Rust 無(wú)需垃圾回收(garbage collector)即可保障內(nèi)存安全,因此理解 Rust 中所有權(quán)如何工作是十分重要的。

所有程序都必須管理其運(yùn)行時(shí)使用計(jì)算機(jī)內(nèi)存的方式。一些語(yǔ)言中具有垃圾回收機(jī)制,在程序運(yùn)行時(shí)有規(guī)律地尋找不再使用的內(nèi)存;在另一些語(yǔ)言中,程序員必須親自分配和釋放內(nèi)存。Rust 則選擇了第三種方式:通過(guò)所有權(quán)系統(tǒng)管理內(nèi)存,編譯器在編譯時(shí)會(huì)根據(jù)一系列的規(guī)則進(jìn)行檢查。如果違反了任何這些規(guī)則,程序都不能編譯。在運(yùn)行時(shí),所有權(quán)系統(tǒng)的任何功能都不會(huì)減慢程序。

因?yàn)樗袡?quán)對(duì)很多程序員來(lái)說(shuō)都是一個(gè)新概念,需要一些時(shí)間來(lái)適應(yīng)。好消息是隨著你對(duì) Rust 和所有權(quán)系統(tǒng)的規(guī)則越來(lái)越有經(jīng)驗(yàn),你就越能自然地編寫(xiě)出安全和高效的代碼。

1.1?所有權(quán)規(guī)則

首先,讓我們看一下所有權(quán)的規(guī)則。當(dāng)我們通過(guò)舉例說(shuō)明時(shí),請(qǐng)謹(jǐn)記這些規(guī)則:

  1. Rust 中的每一個(gè)值都有一個(gè)?所有者owner)。
  2. 值在任一時(shí)刻有且只有一個(gè)所有者。
  3. 當(dāng)所有者(變量)離開(kāi)作用域,這個(gè)值將被丟棄。

?1.2 變量作用域

在所有權(quán)的第一個(gè)例子中,我們看看一些變量的?作用域scope)。作用域是一個(gè)項(xiàng)(item)在程序中有效的范圍。假設(shè)有這樣一個(gè)變量:

let a = 12345

變量 a綁定到了一個(gè)字符串字面值,這個(gè)字符串值是硬編碼進(jìn)程序代碼中的。這個(gè)變量從聲明的點(diǎn)開(kāi)始直到當(dāng)前?作用域?結(jié)束時(shí)都是有效的。

fn main() {                // 作用域開(kāi)始處
   let a = 12345;          // 此時(shí),a才開(kāi)始分配存儲(chǔ)空間  
}                          // 作用域開(kāi)始處

其實(shí)變量是否有效與作用域的關(guān)系跟其他編程語(yǔ)言是類似的。

1.3 String 類型

我們已經(jīng)見(jiàn)過(guò)字符串字面值,即被硬編碼進(jìn)程序里的字符串值。字符串字面值是很方便的,不過(guò)它們并不適合使用文本的每一種場(chǎng)景。原因之一就是它們是不可變的。另一個(gè)原因是并非所有字符串的值都能在編寫(xiě)代碼時(shí)就知道:例如,要是想獲取用戶輸入并存儲(chǔ)該怎么辦呢?為此,Rust 有第二個(gè)字符串類型,String。這個(gè)類型管理被分配到堆上的數(shù)據(jù),所以能夠存儲(chǔ)在編譯時(shí)未知大小的文本。可以使用?from?函數(shù)基于字符串字面值來(lái)創(chuàng)建?String,如下:

fn main() {                
    let s = String::from("hello");
    println!("{s}")
}   

這兩個(gè)冒號(hào)?::?是運(yùn)算符,允許將特定的?from?函數(shù)置于?String?類型的命名空間(namespace)下,而不需要使用類似?string_from?這樣的名字。

可以修改此類字符串可變:

fn main() {                
    let mut s = String::from("hello ");
    s.push('w');
    s.push_str("orld");
    println!("{s}")
}                          

那么這里有什么區(qū)別呢?為什么?String?可變而字面值卻不行呢?區(qū)別在于兩個(gè)類型對(duì)內(nèi)存的處理上。

1.4 內(nèi)存與分配

就字符串字面值來(lái)說(shuō),我們?cè)诰幾g時(shí)就知道其內(nèi)容,所以文本被直接硬編碼進(jìn)最終的可執(zhí)行文件中。這使得字符串字面值快速且高效。不過(guò)這些特性都只得益于字符串字面值的不可變性。不幸的是,我們不能為了每一個(gè)在編譯時(shí)大小未知的文本而將一塊內(nèi)存放入二進(jìn)制文件中,并且它的大小還可能隨著程序運(yùn)行而改變。

對(duì)于?String?類型,為了支持一個(gè)可變,可增長(zhǎng)的文本片段,需要在堆上分配一塊在編譯時(shí)未知大小的內(nèi)存來(lái)存放內(nèi)容。這意味著:

  • 必須在運(yùn)行時(shí)向內(nèi)存分配器(memory allocator)請(qǐng)求內(nèi)存。
  • 需要一個(gè)當(dāng)我們處理完?String?時(shí)將內(nèi)存返回給分配器的方法。

第一部分由我們完成:當(dāng)調(diào)用?String::from?時(shí),它的實(shí)現(xiàn) (implementation) 請(qǐng)求其所需的內(nèi)存。這在編程語(yǔ)言中是非常通用的。

然而,第二部分實(shí)現(xiàn)起來(lái)就各有區(qū)別了。在有?垃圾回收garbage collector,GC)的語(yǔ)言中,GC 記錄并清除不再使用的內(nèi)存,而我們并不需要關(guān)心它。在大部分沒(méi)有 GC 的語(yǔ)言中,識(shí)別出不再使用的內(nèi)存并調(diào)用代碼顯式釋放就是我們的責(zé)任了,跟請(qǐng)求內(nèi)存的時(shí)候一樣。從歷史的角度上說(shuō)正確處理內(nèi)存回收曾經(jīng)是一個(gè)困難的編程問(wèn)題。如果忘記回收了會(huì)浪費(fèi)內(nèi)存。如果過(guò)早回收了,將會(huì)出現(xiàn)無(wú)效變量。如果重復(fù)回收,這也是個(gè) bug。我們需要精確的為一個(gè)?allocate?配對(duì)一個(gè)?free

Rust 采取了一個(gè)不同的策略:內(nèi)存在擁有它的變量離開(kāi)作用域后就被自動(dòng)釋放。

這是一個(gè)將?String?需要的內(nèi)存返回給分配器的很自然的位置:當(dāng)變量離開(kāi)作用域,Rust 為我們調(diào)用一個(gè)特殊的函數(shù)。這個(gè)函數(shù)叫做?drop,在這里?String?的作者可以放置釋放內(nèi)存的代碼。Rust 在結(jié)尾的?}?處自動(dòng)調(diào)用?drop。

注意:在 C++ 中,這種 item 在生命周期結(jié)束時(shí)釋放資源的模式有時(shí)被稱作?資源獲取即初始化Resource Acquisition Is Initialization (RAII))。如果你使用過(guò) RAII 模式的話應(yīng)該對(duì) Rust 的?drop?函數(shù)并不陌生。

變量與數(shù)據(jù)交互的方式(一):移動(dòng)

fn main() {
    let x = 5;
    let y = x;
}

定義的2個(gè)簡(jiǎn)單變量,會(huì)直接存儲(chǔ)在棧中,因?yàn)樗鼈兊拈L(zhǎng)度都是固定的。

fn main() {
    let s1 = String::from("hello");
    let s2 = s1;
}

當(dāng)s1、s2存儲(chǔ)的時(shí)候,會(huì)在堆中開(kāi)辟一片區(qū)域用來(lái)存儲(chǔ),s1和s2 則通過(guò)指針的方式,來(lái)指向堆中存儲(chǔ)值得位置,這樣可以避免在堆中多次開(kāi)辟存儲(chǔ)空間,如果你在其他語(yǔ)言中聽(tīng)說(shuō)過(guò)術(shù)語(yǔ)?淺拷貝shallow copy)和?深拷貝deep copy),那么拷貝指針、長(zhǎng)度和容量而不拷貝數(shù)據(jù)可能聽(tīng)起來(lái)像淺拷貝。不過(guò)因?yàn)?Rust 同時(shí)使第一個(gè)變量無(wú)效了,這個(gè)操作被稱為?移動(dòng)move),而不是叫做淺拷貝。上面的例子可以解讀為?s1?被?移動(dòng)?到了?s2?中。如果打印s1會(huì)出現(xiàn)以下錯(cuò)誤:

Rust核心功能之一(所有權(quán)),Rust,rust,開(kāi)發(fā)語(yǔ)言,后端?

變量與數(shù)據(jù)交互的方式(二):克隆

?如果我們?確實(shí)?需要深度復(fù)制?String?中堆上的數(shù)據(jù),而不僅僅是棧上的數(shù)據(jù),可以使用一個(gè)叫做?clone?的通用函數(shù)。

以下是一個(gè)示例:

fn main() {                
    let s1 = String::from("hello ");
    let s2 = s1.clone();
    println!("{s1} {s2}")
}       

打印以下看下結(jié)果:

Rust核心功能之一(所有權(quán)),Rust,rust,開(kāi)發(fā)語(yǔ)言,后端

只在棧上的數(shù)據(jù):拷貝

fn main() {
    let x = 5;
    let y = x;

    println!("x = {}, y = {}", x, y);
}

?Rust 有一個(gè)叫做?Copy?trait 的特殊注解,可以用在類似整型這樣的存儲(chǔ)在棧上的類型上。如果一個(gè)類型實(shí)現(xiàn)了?Copy?trait,那么一個(gè)舊的變量在將其賦值給其他變量后仍然可用。

那么哪些類型實(shí)現(xiàn)了Copy Trait呢,有以下類型:

  • 所有整數(shù)類型,比如?u32。
  • 布爾類型,bool,它的值是?true?和?false。
  • 所有浮點(diǎn)數(shù)類型,比如?f64。
  • 字符類型,char。
  • 元組,當(dāng)且僅當(dāng)其包含的類型也都實(shí)現(xiàn)?Copy?的時(shí)候。比如,(i32, i32)?實(shí)現(xiàn)了?Copy,但?(i32, String)?就沒(méi)有。

1.5 所有權(quán)與函數(shù)

將值傳遞給函數(shù)與給變量賦值的原理相似。向函數(shù)傳遞值可能會(huì)移動(dòng)或者復(fù)制,就像賦值語(yǔ)句一樣。

一個(gè)示例:

fn main() {
    let s = String::from("hello");  // s 進(jìn)入作用域

    takes_ownership(s);             // s 的值移動(dòng)到函數(shù)里 ...
                                    // ... 所以到這里不再有效

    let x = 5;                      // x 進(jìn)入作用域

    makes_copy(x);                  // x 應(yīng)該移動(dòng)函數(shù)里,
                                    // 但 i32 是 Copy 的,
                                    // 所以在后面可繼續(xù)使用 x

} // 這里,x 先移出了作用域,然后是 s。但因?yàn)?s 的值已被移走,
  // 沒(méi)有特殊之處

fn takes_ownership(some_string: String) { // some_string 進(jìn)入作用域
    println!("{}", some_string);
} // 這里,some_string 移出作用域并調(diào)用 `drop` 方法。
  // 占用的內(nèi)存被釋放

fn makes_copy(some_integer: i32) { // some_integer 進(jìn)入作用域
    println!("{}", some_integer);
} // 這里,some_integer 移出作用域。沒(méi)有特殊之處

可以發(fā)現(xiàn)在值傳遞給函數(shù)的時(shí)候,堆里的數(shù)據(jù)會(huì)移除當(dāng)前作用域,例如,s傳遞takes_ownership方法里,在當(dāng)前作用域s的值被釋放,棧里的值,傳遞給函數(shù),它對(duì)應(yīng)的操作是復(fù)制,例如,x=5傳遞給函數(shù)之后,在當(dāng)前作用域還是可以訪問(wèn)的。

Rust核心功能之一(所有權(quán)),Rust,rust,開(kāi)發(fā)語(yǔ)言,后端

Rust核心功能之一(所有權(quán)),Rust,rust,開(kāi)發(fā)語(yǔ)言,后端

1.6 返回值與作用域

返回值也可以轉(zhuǎn)移所有權(quán)。以下是一個(gè)示例:

fn main() {
    let s1 = gives_ownership();         // gives_ownership 將返回值
                                        // 轉(zhuǎn)移給 s1

    let s2 = String::from("hello");     // s2 進(jìn)入作用域

    let s3 = takes_and_gives_back(s2);  // s2 被移動(dòng)到
                                        // takes_and_gives_back 中,
                                        // 它也將返回值移給 s3
} // 這里,s3 移出作用域并被丟棄。s2 也移出作用域,但已被移走,
  // 所以什么也不會(huì)發(fā)生。s1 離開(kāi)作用域并被丟棄

fn gives_ownership() -> String {             // gives_ownership 會(huì)將
                                             // 返回值移動(dòng)給
                                             // 調(diào)用它的函數(shù)

    let some_string = String::from("yours"); // some_string 進(jìn)入作用域。

    some_string                              // 返回 some_string 
                                             // 并移出給調(diào)用的函數(shù)
                                             // 
}

// takes_and_gives_back 將傳入字符串并返回該值
fn takes_and_gives_back(a_string: String) -> String { // a_string 進(jìn)入作用域
                                                      // 

    a_string  // 返回 a_string 并移出給調(diào)用的函數(shù)
}

這里跟上面移動(dòng)規(guī)則一樣,將值賦給另一個(gè)變量時(shí)移動(dòng)它。當(dāng)持有堆中數(shù)據(jù)值的變量離開(kāi)作用域時(shí),其值將通過(guò)?drop?被清理掉,除非數(shù)據(jù)被移動(dòng)為另一個(gè)變量所有。

以上我們都是通過(guò)一個(gè)變量來(lái)獲取所有,這樣來(lái)回賦值就會(huì)有些啰嗦,這樣的話,我們可以使用元組來(lái)返回多個(gè)值。

fn main() {
    let s1 = String::from("hello");

    let (s2, len) = calculate_length(s1);

    println!("The length of '{}' is {}.", s2, len);
}

fn calculate_length(s: String) -> (String, usize) {
    let length = s.len(); // len() 返回字符串的長(zhǎng)度

    (s, length)
}

但是這未免有些形式主義,而且這種場(chǎng)景應(yīng)該很常見(jiàn)。幸運(yùn)的是,Rust 對(duì)此提供了一個(gè)不用獲取所有權(quán)就可以使用值的功能,叫做?引用references),后面我們?cè)賮?lái)看看引用是什么?文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-758934.html

到了這里,關(guān)于Rust核心功能之一(所有權(quán))的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 【Rust】Rust學(xué)習(xí) 第四章認(rèn)識(shí)所有權(quán)

    【Rust】Rust學(xué)習(xí) 第四章認(rèn)識(shí)所有權(quán)

    所有權(quán)(系統(tǒng))是 Rust 最為與眾不同的特性,它讓 Rust 無(wú)需垃圾回收(garbage collector)即可保障內(nèi)存安全。因此,理解 Rust 中所有權(quán)如何工作是十分重要的。 4.1?所有權(quán) 所有運(yùn)行的程序都必須管理其使用計(jì)算機(jī)內(nèi)存的方式。一些語(yǔ)言中具有垃圾回收機(jī)制,在程序運(yùn)行時(shí)不斷地

    2024年02月13日
    瀏覽(21)
  • Rust-所有權(quán)(ownership)

    Rust入門(mén)學(xué)習(xí)系列-Rust 的核心功能(之一)是 所有權(quán)(ownership)。引入這個(gè)概念是為了更好的管理計(jì)算機(jī)的內(nèi)存。下面篇幅讓我們來(lái)研究下這個(gè)功能有什么神奇之處。 常見(jiàn)的編程語(yǔ)言中計(jì)算機(jī)內(nèi)存管理方式: Java:Java使用Java虛擬機(jī)(JVM)來(lái)管理計(jì)算機(jī)內(nèi)存。JVM有一個(gè)垃圾回收

    2024年02月19日
    瀏覽(31)
  • 【rust】| 06——語(yǔ)言特性 | 所有權(quán)

    【rust】| 06——語(yǔ)言特性 | 所有權(quán)

    系列文章目錄 【rust】| 00——開(kāi)發(fā)環(huán)境搭建 【rust】| 01——編譯并運(yùn)行第一個(gè)rust程序 【rust】| 02——語(yǔ)法基礎(chǔ) | 變量(不可變?)和常量 【rust】| 03——語(yǔ)法基礎(chǔ) | 數(shù)據(jù)類型 【rust】| 04——語(yǔ)法基礎(chǔ) | 函數(shù) 【rust】| 05——語(yǔ)法基礎(chǔ) | 流程控制 【rust】| 06——語(yǔ)言特性 | 所有權(quán) ?

    2024年02月04日
    瀏覽(30)
  • rust學(xué)習(xí)——棧、堆、所有權(quán)

    rust學(xué)習(xí)——棧、堆、所有權(quán)

    棧和堆是編程語(yǔ)言最核心的數(shù)據(jù)結(jié)構(gòu),但是在很多語(yǔ)言中,你并不需要深入了解棧與堆。 但對(duì)于 Rust 這樣的系統(tǒng)編程語(yǔ)言,值是位于棧上還是堆上非常重要, 因?yàn)檫@會(huì)影響程序的行為和性能。 棧和堆的核心目標(biāo)就是為程序在運(yùn)行時(shí)提供可供使用的內(nèi)存空間。 棧 棧按照順序存

    2024年02月07日
    瀏覽(31)
  • Rust-所有權(quán)和移動(dòng)語(yǔ)義

    Rust-所有權(quán)和移動(dòng)語(yǔ)義

    拿C語(yǔ)言的代碼來(lái)打個(gè)比方。我們可能會(huì)在堆上創(chuàng)建一個(gè)對(duì)象,然后使用一個(gè)指針來(lái)管理這個(gè)對(duì)象: 接下來(lái),我們可能需要使用這個(gè)對(duì)象: 然而,這段代碼之后,誰(shuí)能猜得到,指針p指向的對(duì)象究竟發(fā)生了什么?它是否被修改過(guò)了?它還存在嗎,是否已經(jīng)被釋放?是否有另外一個(gè)指

    2024年01月18日
    瀏覽(25)
  • Rust語(yǔ)言從入門(mén)到入坑——(5)Rust 所有權(quán)

    Rust語(yǔ)言從入門(mén)到入坑——(5)Rust 所有權(quán)

    主要介紹Rust所有權(quán)的知識(shí),涉及到變量的作用域,內(nèi)存釋放機(jī)制,移動(dòng),克隆,引用等知識(shí),很多知識(shí)是Rust語(yǔ)言特有機(jī)制。 所有權(quán)有以下三條規(guī)則: - Rust 中的每個(gè)值都有一個(gè)變量,稱為其所有者。 - 一次只能有一個(gè)所有者。 - 當(dāng)所有者不在程序運(yùn)行范圍時(shí),該值將被刪除

    2024年02月10日
    瀏覽(19)
  • Rust語(yǔ)法:所有權(quán)&引用&生命周期

    Rust語(yǔ)法:所有權(quán)&引用&生命周期

    垃圾回收管理內(nèi)存 Python,Java這類語(yǔ)言在管理內(nèi)存時(shí)引用了一種叫做垃圾回收的技術(shù),這種技術(shù)會(huì)為每個(gè)變量設(shè)置一個(gè)引用計(jì)數(shù)器(reference counter),來(lái)統(tǒng)計(jì)每個(gè)對(duì)象的引用次數(shù)。 一旦某個(gè)對(duì)象的引用數(shù)為0,垃圾回收器就會(huì)擇取一個(gè)時(shí)機(jī)將其所占用的空間回收。 以Python為例子

    2024年02月12日
    瀏覽(24)
  • 30天拿下Rust之所有權(quán)

    概述 ????????在編程語(yǔ)言的世界中,Rust憑借其獨(dú)特的所有權(quán)機(jī)制脫穎而出,為開(kāi)發(fā)者提供了一種新穎而強(qiáng)大的工具來(lái)防止內(nèi)存錯(cuò)誤。這一特性不僅確保了代碼的安全性,還極大地提升了程序的性能。在Rust中,所有權(quán)是一種編譯時(shí)檢查機(jī)制,用于追蹤哪些內(nèi)存或資源何時(shí)可

    2024年03月08日
    瀏覽(24)
  • 【跟小嘉學(xué) Rust 編程】四、理解 Rust 的所有權(quán)概念

    【跟小嘉學(xué) Rust 編程】四、理解 Rust 的所有權(quán)概念

    【跟小嘉學(xué) Rust 編程】一、Rust 編程基礎(chǔ) 【跟小嘉學(xué) Rust 編程】二、Rust 包管理工具使用 【跟小嘉學(xué) Rust 編程】三、Rust 的基本程序概念 【跟小嘉學(xué) Rust 編程】四、理解 Rust 的所有權(quán)概念 本章節(jié)將講解 Rust 獨(dú)有的概念(所有權(quán))。所有權(quán)是 Rust 最獨(dú)特的特性,它使得 Rust 能夠

    2024年02月10日
    瀏覽(31)
  • Rust 基礎(chǔ)入門(mén) —— 2.3.所有權(quán)和借用

    Rust 的最主要光芒: 內(nèi)存安全 。 實(shí)現(xiàn)方式: 所有權(quán)系統(tǒng) 。 因?yàn)槲覀冞@里實(shí)際講述的內(nèi)容是關(guān)于 內(nèi)存安全的,所以我們最好先復(fù)習(xí)一下內(nèi)存的知識(shí)。 然后我們,需要理解的就只有所有權(quán)概念,以及為了開(kāi)發(fā)便利,進(jìn)一步引出的引用借用概念。 內(nèi)存作為存儲(chǔ)程序運(yùn)行時(shí)數(shù)據(jù)

    2024年02月12日
    瀏覽(28)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包