最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

為什么要使用 Rust 語言、Rust 語言有什么優(yōu)勢

 更新時間:2022年10月09日 16:01:34   作者:人郵異步社區(qū)  
雖然 Rust 是一種通用的多范式語言,但它的目標是 C 和 C++占主導地位的系統(tǒng)編程領域,很多朋友會問rust語言難學嗎?rust語言可以做什么,今天帶著這些疑問通過本文詳細介紹下,感興趣的朋友一起看看吧

Rust 是一種采用過去的知識解決將來的問題的技術。” ——Graydon Hoare

Rust 是一種快速、高并發(fā)、安全且具有授權性的編程語言,最初由 Graydon Hoare 于2006 年創(chuàng)造和發(fā)布?,F(xiàn)在它是一種開源語言,主要由 Mozilla 團隊和許多開源社區(qū)成員共同維護和開發(fā)。

雖然 Rust 是一種通用的多范式語言,但它的目標是 C 和 C++占主導地位的系統(tǒng)編程領域。這意味著你可以使用 Rust 編寫操作系統(tǒng)、游戲引擎和許多性能關鍵型應用程序。同時,它還具有足夠的表現(xiàn)力,你可以使用它構建高性能的 Web 應用程序、網絡服務,類型安全的數據庫對象關系映射(Object Relational Mapping,ORM)庫,還可以將程序編譯成WebAssembly 在 Web 瀏覽器上運行。Rust 還在為嵌入式平臺構建安全性優(yōu)先的實時應用程序方面獲得了相當大的關注,例如 Arm 基于 Cortex-M 的微控制器,目前該領域主要由 C語言主導。Rust 因其廣泛的適用性在多個領域都表現(xiàn)良好,這在單一編程語言中是非常罕見的。

Rust 作為一門靜態(tài)和強類型語言而存在。靜態(tài)屬性意味著編譯器在編譯時具有所有相關變量和類型的信息,并且在編譯時會進行大量檢查,在運行時只保留少量的類型檢查。它的強類型屬性意味著不允許發(fā)生諸如類型之間自動轉換的事情,并且指向整數的變量不能在代碼中更改為指向字符串。例如在 JavaScript 等弱類型語言中,你可以輕松地執(zhí)行類似“two = "2"; two = 2 + two;”這樣的操作。JavaScript 在運行時將 2 的類型弱化為字符串,因此會將 22 作為字符串存儲到變量 two 中,這與你的意圖完全相反并且毫無意義。在 Rust 中,與上述代碼意義相同的代碼是“let mut two = "2"; two = 2 + two;”,該代碼將會在編譯時捕獲異常,并提示信息:“cannot add '&str' to '{integer}'”。

因此,強類型屬性使 Rust 可以安全地重構代碼,并在編譯時捕獲大多數錯誤,而不是在運行時出錯。用 Rust 編寫的程序表現(xiàn)力和性能都非常好,因為使用它你可以擁有高級函數式語言的大部分特性,例如高階函數和惰性迭代器,這些特性使你可以編譯像 C/C++程序這樣高效的程序。它的很多設計決策中強調的首要理念是編譯期內存安全、零成本抽象和支持高并發(fā)。讓我們來詳細說明這些理念。

編譯期內存安全:Rust 編譯期可以在編譯時跟蹤程序中資源的變量,并在沒有垃圾收集器(Garbage Collectors,GC)的情況下完成所有這些操作。

這意味你不會遇到在 free、double free 命令之后調用指針,或者運行時掛起指針等“臭名昭著”的問題。Rust 中的引用類型(類型名稱前面帶有&標記的類型)與生命周期標記隱式關聯(lián)('foo),有時由程序員顯式聲明。在生命周期中,編譯器可以跟蹤代碼中可以安全使用的位置,如果它是非法的,那么會在編譯期報告異常。為了實現(xiàn)這一點,Rust 通過這些引用上的生命周期標簽來運行借用/引用檢查算法,以確保你永遠不能訪問已釋放的內存地址。這樣做也可以防止你釋放被其他某些變量調用的任何指針。

零成本抽象:編程的目的就是管理復雜性,這是通過良好的抽象來實現(xiàn)的。接下來讓我們來看一個 Rust 和 Kotlin 的良好抽象示例。抽象讓我們能夠編寫高級并且易于閱讀和推斷的代碼。我們將比較 Kotlin 的流和 Rust 的迭代器在處理數字列表時的性能,并參照 Rust提供的零成本抽象原則。這里的抽象是指能夠使用以其他方法作為參數的方法,根據條件過濾數字而不使用手動循環(huán)。在這里引入 Kotlin 是因為它看上去和 Rust 存在相似性。代碼很容易理解,我們的目標是給出更高層面的解釋,并對代碼中的細節(jié)進行詳細闡述,因為這個示例的重點是理解零成本特性。

首先,我們來看 Kotlin 中的代碼:

 import java.util.stream.Collectors  
  
 fun main(args: Array<String>)  
 {  
     //創(chuàng)建數字流 
     val numbers = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10).stream()  
     val evens = numbers.filter { it -> it % 2 == 0 }  
     val evenSquares  = evens.map { it -> it * it }  
     val result = evenSquares.collect(Collectors.toList())  
    println(result)       // prints [4,16,36,64,100]  
 
    println(evens) 
    println(evenSquares) 
 }

我們創(chuàng)建了一個數字流(第 6 行)并調用了一系列方法(filter 和 map)來轉換元素, 以收集僅包含偶數的序列。這些方法可以采用閉包或函數(第 8 行中的“ it -> it * it”)來轉換集合中的元素。在函數式編程語言中,當我們在流/迭代器上調用這些方法時,對于每個這樣的調用,該語言會創(chuàng)建一個中間對象來保存與正在執(zhí)行的操作有關的任何狀態(tài)或元數據。因此,evens 和 evenSquares 將在 JVM 堆上分配兩個不同的中間對象。在堆上分配資源將會產生內存開銷,這是我們在 Kotlin 中為抽象必須額外付出的代價。

當我們輸出 evens 和 evenSquares 的值時,確實得到了兩個不同的對象,如下所示:

java.util.stream.ReferencePipeline$Head@51521cc1  
java.util.stream.ReferencePipeline$3@1b4fb997 

@之后的十六進制值是 JVM 對象的哈希值。由于哈希值不同,所以它們是不同的對象。在 Rust 中,我們會做相同的事情:

 fn main() {  
     let numbers = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10].into_iter();  
     let evens = numbers.filter(|x| *x % 2 == 0);  
     let even_squares = evens.clone().map(|x| x * x);  
     let result = even_squares.clone().collect::<Vec<_>>();  
     println!("{:?}", result); // 輸出 [4,16,36,64,100]  
     println!("{:?}\n{:?}", evens, even_squares);  
 } 

接下來將解釋上述代碼的細節(jié)。在第 2 行中,我們調用 vec![]創(chuàng)建一個數字列表,然 后調用 into_iter()方法使其成為一個數字的迭代器/流。使用 into_iter()方法從集合中創(chuàng)建 了一個包裝器的迭代器類型(這里 Vec<i32>是一個有符號的 32 位整數列表),即 IntoIter([1,2,3,4,5,6, 7,8,9,10]),此迭代器類型引用原始的數字列表。然后我們執(zhí)行 filter 和 map 轉換(第 3 行和第 4 行),就像我們在 Kotlin 中所做的那樣。第 7 行輸出 evens 和 even_squares 的類型,如下所示(為了簡潔,省略了一些細節(jié)):

evens:        Filter { iter: IntoIter( <numbers> ) }  
even_squares: Map { iter: Filter { iter: IntoIter( <numbers> ) }} 

中間對象 Filter 和 Map 是基礎迭代器結構上的包裝器類型(未在堆上分配),它本身是一個包裝器,包含對第 2 行的原始數字列表的引用。第 4 行和第 5 行的包裝器結構在分別調用 filter 和 map 時創(chuàng)建,它們之間沒有任何指針解引用,并且不會像 Kotlin 那樣產生堆分配的開銷。所有這些可歸結為高效的匯編代碼,這相當于使用循環(huán)(語句)的手動編寫版本。

支持高并發(fā):當我們說 Rust 是并發(fā)安全的時,其含義是該語言具有應用程序接口(Application Programming Interface,API)和抽象能力,使得編寫正確和安全的并發(fā)代碼變得非常容易。而在 C++中,并發(fā)代碼出錯的可能性非常大。在 C++中同步訪問多個線程的數據時,需要在每次進入臨界區(qū)時調用 mutex.lock(),并在退出它時調用 mutex.unlock():

// C++  
mutex.lock();          // 互斥鎖鎖定 
 // 執(zhí)行某些關鍵操作 
mutex.unlock();        // 執(zhí)行完畢

在大量開發(fā)人員共同協(xié)作的大型代碼庫中,你可能會忘記在多線程訪問共享對象之前調用 mutex.lock(),這可能導致數據訪問沖突。在其他情況下,你可能忘記解開互斥鎖(Mutex),并使其他想要訪問數據的線程一直處于等待狀態(tài)。

Rust 對此有不同的處理方式。在這里,你將數據包裝成 Mutex 類型,以確保來自多個線程的數據進行同步可變訪問:

// Rust  
use std::sync::Mutex;  
fn main() {  
    let value = Mutex::new(23);  
    *value.lock().unwrap() += 1;         // 執(zhí)行一些修改 
}                                        // 這里自動解鎖

在上述代碼中,我們能夠在變量 value 調用 lock()方法之后修改數據。Rust 采用了保護共享數據自身,而不是代碼的概念。Rust 與 Mutex 和受保護的數據的交互并不是獨立的,這和 C++中的情況一樣。你無法在 Mutex 類型不調用 lock()方法的情況下訪問內部數據。

那么 lock()方法的作用是什么?調用 lock()方法之后會返回一個名為 MutexGuard 的東西,它會在變量超出作用域范圍之后自動解除鎖定,它是 Rust 提供的眾多安全并發(fā)抽象之一。

另一個新穎的想法是標記特征的概念,它在編譯期驗證,并確保在并發(fā)代碼中同步和安全地訪問數據,第 4 章詳細介紹了該特征。類型會被稱為 Send 和 Sync 的標記特征進行注釋標記,以指示它們是否可以安全地發(fā)送到線程或者在線程之間共享。當程序向線程發(fā)送值時,編譯器會檢查該值是否實現(xiàn)了所需的標記特征,如果沒有,則禁止使用該值。通過這種方式,Rust 允許你毫無顧慮地編寫并發(fā)代碼,編譯器在編譯時會捕獲多線程代碼中的異常。

編寫并發(fā)代碼已經很難了,使用 C/C++會讓它變得更加困難和神秘。當前 CPU 沒有獲得更多的時鐘頻率;相反,我們添加了更多內核。因此,并發(fā)編程是正確的發(fā)展方向。Rust 使得編寫并發(fā)代碼變得輕而易舉,并且降低了編寫安全的并發(fā)代碼的門檻。

Rust 還借鑒了 C++的 RAII 原則用于資源初始化,這種技術的本質是將資源的生命周期和對象的生命周期綁定,而堆分配類型的解除分配是通過執(zhí)行 drop 特征上的 drop()方法實現(xiàn)的。當變量超出作用域時,程序會自動調用此方法。它還用 Result 和 Option 類型替代了空指針的概念,我們將在第 6 章對此進行詳細介紹。這意味著 Rust 不允許代碼中出現(xiàn)null/undefined 的值,除非通過外部函數接口與其他語言交互,以及使用不安全代碼時。該語言還強調組合,而不是繼承,并且有一套特征系統(tǒng),它由數據類型實現(xiàn),類似于 Haskell的類型類,也被稱為加強型的 Java 接口。

但同樣重要的是,Rust 社區(qū)非?;钴S和友好。該語言包含非常全面的文檔,可以在Rust 官網中找到。Rust 在 Stack Overflow 的開發(fā)者調查上連續(xù) 3 年(2016 年、2017 年和2018 年)被評為最受歡迎的編程語言,因此編程社區(qū)對它非常青睞??偠灾?,如果你希望編寫具有較少錯誤的高性能軟件,又希望感受當前流行語言的特性和極佳的社區(qū)文化, 那么 Rust 應該是一個不錯的選擇。

到此這篇關于為什么要使用 Rust 語言、Rust 語言有什么優(yōu)勢的文章就介紹到這了,更多相關Rust 語言優(yōu)勢內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

您可能感興趣的文章:

相關文章

  • Rust語言從入門到精通之Tokio的Channel深入理解

    Rust語言從入門到精通之Tokio的Channel深入理解

    這篇文章主要為大家介紹了Rust語言從入門到精通之Tokio的Channel深入理解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-05-05
  • Rust語言之結構體和枚舉的用途與高級功能詳解

    Rust語言之結構體和枚舉的用途與高級功能詳解

    Rust 是一門注重安全性和性能的現(xiàn)代編程語言,其中結構體和枚舉是其強大的數據類型之一,了解結構體和枚舉的概念及其高級功能,將使你能夠更加靈活和高效地處理數據,本文將深入探討 Rust 中的結構體和枚舉,并介紹它們的用途和高級功能
    2023-10-10
  • 使用systemd部署r-nacos的操作方法

    使用systemd部署r-nacos的操作方法

    r-nacos是一個用rust實現(xiàn)的nacos服務,我們用它平替java?nacos以降低服務占用內存,提升服務的穩(wěn)定性,這篇文章主要介紹了使用systemd部署r-nacos,需要的朋友可以參考下
    2024-03-03
  • Rust中使用Serde對json數據進行反序列化

    Rust中使用Serde對json數據進行反序列化

    JSON作為目前流行的數據格式之一,被大家廣泛使用,在日常的開發(fā)實踐中,將JSON數據反序列化為對應的類型具有重要的意義,在Rust中,Serde幾乎成了JSON數據解析的事實標準,本文將給大家介紹Rust中使用Serde對json數據進行反序列化,需要的朋友可以參考下
    2024-01-01
  • Rust實現(xiàn)grep命令行工具的方法

    Rust實現(xiàn)grep命令行工具的方法

    這篇文章主要介紹了Rust實現(xiàn)grep命令行工具的方法,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-07-07
  • Rust語言從入門到精通系列之Iterator迭代器深入詳解

    Rust語言從入門到精通系列之Iterator迭代器深入詳解

    這篇文章主要為大家介紹了Rust語言從入門到精通系列之Iterator迭代器深入詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-04-04
  • rust聲明式宏的實現(xiàn)

    rust聲明式宏的實現(xiàn)

    聲明式宏使得你能夠寫出類似?match?表達式的東西,來操作你所提供的?Rust代碼,它使用你提供的代碼來生成用于替換宏調用的代碼,感興趣的可以了解一下
    2023-12-12
  • rust標準庫std::env環(huán)境相關的常量

    rust標準庫std::env環(huán)境相關的常量

    在本章節(jié)中, 我們探討了Rust處理命令行參數的常見的兩種方式和處理環(huán)境變量的兩種常見方式, 拋開Rust的語法, 實際上在命令行參數的處理方式上, 與其它語言大同小異, 可能影響我們習慣的也就只剩下語法,本文介紹rust標準庫std::env的相關知識,感興趣的朋友一起看看吧
    2024-03-03
  • Rust Struct結構體詳解

    Rust Struct結構體詳解

    結構體,是一種自定義數據類型,允許程序員將不同類型的數據結合起來,形成相關聯(lián)的整體。Rust的結構體還提供方法和關聯(lián)函數,可以指定那些與結構體數據相關的行為
    2022-10-10
  • Rust?搭建一個小程序運行環(huán)境的方法詳解

    Rust?搭建一個小程序運行環(huán)境的方法詳解

    rust是一門比較新的編程語言,2015年5月15日,Rust編程語言核心團隊正式宣布發(fā)布Rust?1.0版本,本文給大家介紹Rust?搭建一個小程序運行環(huán)境,以iOS?為例介紹開發(fā)環(huán)境的準備,感興趣的朋友跟隨小編一起看看吧
    2022-05-05

最新評論

沅陵县| 吉木萨尔县| 岫岩| 永登县| 共和县| 丰镇市| 新乡市| 新竹市| 台南县| 镇原县| 邳州市| 建瓯市| 台山市| 沙洋县| 通山县| 富顺县| 湖南省| 吉安县| 乌拉特前旗| 鱼台县| 靖西县| 定陶县| 竹山县| 望江县| 忻州市| 怀柔区| 六枝特区| 太白县| 桓仁| 吉木萨尔县| 吴堡县| 开江县| 固镇县| 河西区| 巴塘县| 蛟河市| 宝鸡市| 望江县| 屯门区| 巩义市| 普兰县|