我的编程空间,编程开发者的网络收藏夹
学习永远不晚

为什么要使用Rust语言、Rust语言有什么优势

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

为什么要使用Rust语言、Rust语言有什么优势

Rust 是一种采用过去的知识解决将来的问题的技术。” ——Graydon Hoare

Rust 是一种快速、高并发、安全且具有授权性的编程语言,最初由 Graydon Hoare 于2006 年创造和发布。现在它是一种开源语言,主要由 Mozilla 团队和许多开源社区成员共同维护和开发。

虽然 Rust 是一种通用的多范式语言,但它的目标是 C 和 C++占主导地位的系统编程领域。这意味着你可以使用 Rust 编写操作系统、游戏引擎和许多性能关键型应用程序。同时,它还具有足够的表现力,你可以使用它构建高性能的 Web 应用程序、网络服务,类型安全的数据库对象关系映射(Object Relational Mapping,ORM)库,还可以将程序编译成WebAssembly 在 Web 浏览器上运行。Rust 还在为嵌入式平台构建安全性优先的实时应用程序方面获得了相当大的关注,例如 Arm 基于 Cortex-M 的微控制器,目前该领域主要由 C语言主导。Rust 因其广泛的适用性在多个领域都表现良好,这在单一编程语言中是非常罕见的。

Rust 作为一门静态和强类型语言而存在。静态属性意味着编译器在编译时具有所有相关变量和类型的信息,并且在编译时会进行大量检查,在运行时只保留少量的类型检查。它的强类型属性意味着不允许发生诸如类型之间自动转换的事情,并且指向整数的变量不能在代码中更改为指向字符串。例如在 JavaScript 等弱类型语言中,你可以轻松地执行类似“two = "2"; two = 2 + two;”这样的操作。JavaScript 在运行时将 2 的类型弱化为字符串,因此会将 22 作为字符串存储到变量 two 中,这与你的意图完全相反并且毫无意义。在 Rust 中,与上述代码意义相同的代码是“let mut two = "2"; two = 2 + two;”,该代码将会在编译时捕获异常,并提示信息:“cannot add '&str' to '{integer}'”。

因此,强类型属性使 Rust 可以安全地重构代码,并在编译时捕获大多数错误,而不是在运行时出错。用 Rust 编写的程序表现力和性能都非常好,因为使用它你可以拥有高级函数式语言的大部分特性,例如高阶函数和惰性迭代器,这些特性使你可以编译像 C/C++程序这样高效的程序。它的很多设计决策中强调的首要理念是编译期内存安全、零成本抽象和支持高并发。让我们来详细说明这些理念。

编译期内存安全:Rust 编译期可以在编译时跟踪程序中资源的变量,并在没有垃圾收集器(Garbage Collectors,GC)的情况下完成所有这些操作。

这意味你不会遇到在 free、double free 命令之后调用指针,或者运行时挂起指针等“臭名昭著”的问题。Rust 中的引用类型(类型名称前面带有&标记的类型)与生命周期标记隐式关联('foo),有时由程序员显式声明。在生命周期中,编译器可以跟踪代码中可以安全使用的位置,如果它是非法的,那么会在编译期报告异常。为了实现这一点,Rust 通过这些引用上的生命周期标签来运行借用/引用检查算法,以确保你永远不能访问已释放的内存地址。这样做也可以防止你释放被其他某些变量调用的任何指针。

零成本抽象:编程的目的就是管理复杂性,这是通过良好的抽象来实现的。接下来让我们来看一个 Rust 和 Kotlin 的良好抽象示例。抽象让我们能够编写高级并且易于阅读和推断的代码。我们将比较 Kotlin 的流和 Rust 的迭代器在处理数字列表时的性能,并参照 Rust提供的零成本抽象原则。这里的抽象是指能够使用以其他方法作为参数的方法,根据条件过滤数字而不使用手动循环。在这里引入 Kotlin 是因为它看上去和 Rust 存在相似性。代码很容易理解,我们的目标是给出更高层面的解释,并对代码中的细节进行详细阐述,因为这个示例的重点是理解零成本特性。

首先,我们来看 Kotlin 中的代码:

 import java.util.stream.Collectors  
  
 fun main(args: Array<String>)  
 {  
     //创建数字流 
     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) 
 }

我们创建了一个数字流(第 6 行)并调用了一系列方法(filter 和 map)来转换元素, 以收集仅包含偶数的序列。这些方法可以采用闭包或函数(第 8 行中的“ it -> it * it”)来转换集合中的元素。在函数式编程语言中,当我们在流/迭代器上调用这些方法时,对于每个这样的调用,该语言会创建一个中间对象来保存与正在执行的操作有关的任何状态或元数据。因此,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);  
 } 

接下来将解释上述代码的细节。在第 2 行中,我们调用 vec![]创建一个数字列表,然 后调用 into_iter()方法使其成为一个数字的迭代器/流。使用 into_iter()方法从集合中创建 了一个包装器的迭代器类型(这里 Vec<i32>是一个有符号的 32 位整数列表),即 IntoIter([1,2,3,4,5,6, 7,8,9,10]),此迭代器类型引用原始的数字列表。然后我们执行 filter 和 map 转换(第 3 行和第 4 行),就像我们在 Kotlin 中所做的那样。第 7 行输出 evens 和 even_squares 的类型,如下所示(为了简洁,省略了一些细节):

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

中间对象 Filter 和 Map 是基础迭代器结构上的包装器类型(未在堆上分配),它本身是一个包装器,包含对第 2 行的原始数字列表的引用。第 4 行和第 5 行的包装器结构在分别调用 filter 和 map 时创建,它们之间没有任何指针解引用,并且不会像 Kotlin 那样产生堆分配的开销。所有这些可归结为高效的汇编代码,这相当于使用循环(语句)的手动编写版本。

支持高并发:当我们说 Rust 是并发安全的时,其含义是该语言具有应用程序接口(Application Programming Interface,API)和抽象能力,使得编写正确和安全的并发代码变得非常容易。而在 C++中,并发代码出错的可能性非常大。在 C++中同步访问多个线程的数据时,需要在每次进入临界区时调用 mutex.lock(),并在退出它时调用 mutex.unlock():

// C++  
mutex.lock();          // 互斥锁锁定 
 // 执行某些关键操作 
mutex.unlock();        // 执行完毕

在大量开发人员共同协作的大型代码库中,你可能会忘记在多线程访问共享对象之前调用 mutex.lock(),这可能导致数据访问冲突。在其他情况下,你可能忘记解开互斥锁(Mutex),并使其他想要访问数据的线程一直处于等待状态。

Rust 对此有不同的处理方式。在这里,你将数据包装成 Mutex 类型,以确保来自多个线程的数据进行同步可变访问:

// Rust  
use std::sync::Mutex;  
fn main() {  
    let value = Mutex::new(23);  
    *value.lock().unwrap() += 1;         // 执行一些修改 
}                                        // 这里自动解锁

在上述代码中,我们能够在变量 value 调用 lock()方法之后修改数据。Rust 采用了保护共享数据自身,而不是代码的概念。Rust 与 Mutex 和受保护的数据的交互并不是独立的,这和 C++中的情况一样。你无法在 Mutex 类型不调用 lock()方法的情况下访问内部数据。

那么 lock()方法的作用是什么?调用 lock()方法之后会返回一个名为 MutexGuard 的东西,它会在变量超出作用域范围之后自动解除锁定,它是 Rust 提供的众多安全并发抽象之一。

另一个新颖的想法是标记特征的概念,它在编译期验证,并确保在并发代码中同步和安全地访问数据,第 4 章详细介绍了该特征。类型会被称为 Send 和 Sync 的标记特征进行注释标记,以指示它们是否可以安全地发送到线程或者在线程之间共享。当程序向线程发送值时,编译器会检查该值是否实现了所需的标记特征,如果没有,则禁止使用该值。通过这种方式,Rust 允许你毫无顾虑地编写并发代码,编译器在编译时会捕获多线程代码中的异常。

编写并发代码已经很难了,使用 C/C++会让它变得更加困难和神秘。当前 CPU 没有获得更多的时钟频率;相反,我们添加了更多内核。因此,并发编程是正确的发展方向。Rust 使得编写并发代码变得轻而易举,并且降低了编写安全的并发代码的门槛。

Rust 还借鉴了 C++的 RAII 原则用于资源初始化,这种技术的本质是将资源的生命周期和对象的生命周期绑定,而堆分配类型的解除分配是通过执行 drop 特征上的 drop()方法实现的。当变量超出作用域时,程序会自动调用此方法。它还用 Result 和 Option 类型替代了空指针的概念,我们将在第 6 章对此进行详细介绍。这意味着 Rust 不允许代码中出现null/undefined 的值,除非通过外部函数接口与其他语言交互,以及使用不安全代码时。该语言还强调组合,而不是继承,并且有一套特征系统,它由数据类型实现,类似于 Haskell的类型类,也被称为加强型的 Java 接口。

但同样重要的是,Rust 社区非常活跃和友好。该语言包含非常全面的文档,可以在Rust 官网中找到。Rust 在 Stack Overflow 的开发者调查上连续 3 年(2016 年、2017 年和2018 年)被评为最受欢迎的编程语言,因此编程社区对它非常青睐。总而言之,如果你希望编写具有较少错误的高性能软件,又希望感受当前流行语言的特性和极佳的社区文化, 那么 Rust 应该是一个不错的选择。

到此这篇关于为什么要使用 Rust 语言、Rust 语言有什么优势的文章就介绍到这了,更多相关Rust 语言优势内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

为什么要使用Rust语言、Rust语言有什么优势

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Rust语言技巧的使用方法是什么

这篇文章主要介绍“Rust语言技巧的使用方法是什么”,在日常操作中,相信很多人在Rust语言技巧的使用方法是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Rust语言技巧的使用方法是什么”的疑惑有所帮助!
2023-06-16

为什么go和rust语言都舍弃了继承

Go和Rust都是现代编程语言,因为继承会导致代码的复杂性增加,而且继承的实现也会影响代码的性能。 它们的设计目标是简单、高效、安全和可靠。因此,它们都舍弃了传统面向对象语言中的继承特性,因为这种特性会引入很多复杂性和潜在的安全隐患。
为什么go和rust语言都舍弃了继承
2023-10-29

C++语言有什么优势

这篇文章主要讲解了“C++语言有什么优势”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“C++语言有什么优势”吧!入门简介    C++是个强大的语言,可以用于做别的语言做不了的工作。但是,这
2023-06-17

怎么使用Rust语言的类型转换

本篇内容介绍了“怎么使用Rust语言的类型转换”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!什么是类型转换?类型转换,是调用函数时,根据函数
2023-06-16

对比 Go 语言,Kotlin 有什么优势和劣势

对比 Go 语言,Kotlin 主要有以下优劣势:一、更简洁灵活;二、支持多平台;三、不支持并发计算支持;四、运行速度更慢。Kotlin 是多范式语言,对泛型和函数式编程有良好支持,可以写出更简洁和灵活的代码。
对比 Go 语言,Kotlin 有什么优势和劣势
2023-10-29

go语言的优势和劣势是什么

这篇“go语言的优势和劣势是什么”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“go语言的优势和劣势是什么”文章吧。go语言的
2023-07-04

Java语言有什么优点

本篇内容介绍了“Java语言有什么优点”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!  Java是一门全球范围内使用最广泛的,面向对象的编程
2023-06-02

go语言的用途是什么及有哪些优势

这篇文章主要介绍“go语言的用途是什么及有哪些优势”,在日常操作中,相信很多人在go语言的用途是什么及有哪些优势问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”go语言的用途是什么及有哪些优势”的疑惑有所帮助!
2023-07-04

Python编程语言使用中有什么优点

这篇文章主要介绍“Python编程语言使用中有什么优点”,在日常操作中,相信很多人在Python编程语言使用中有什么优点问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Python编程语言使用中有什么优点”的疑
2023-06-17

Kotlin语言有什么用

这篇文章主要为大家展示了“Kotlin语言有什么用”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Kotlin语言有什么用”这篇文章吧。Kotlin 是一种在 Java 虚拟机上运行的静态类型编程
2023-06-27

c#语言有什么用

c# 是一种高级编程语言,广泛应用于构建各种应用程序,包括:桌面应用程序(gui 应用程序、工具和实用程序)移动应用程序(ios、android 和 windows 设备)游戏开发(2d 和 3d 游戏)web 应用程序(web 服务和 w
c#语言有什么用
2024-04-04

VB.NET语言有什么用

这篇文章主要介绍了VB.NET语言有什么用,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。我使用VB.NET的时间越长,我就越是欣赏VB.NET语言和结构。作为一名VB程序员,
2023-06-17

phpmyadmin使用什么语言

phpmyadmin 使用多种编程语言来实现其功能,包括 php 作为核心语言,javascript、css、html、sql 和 c 用于其他方面。它支持多语言翻译,允许用户根据他们的浏览器首选项或手动选择来使用他们的母语。PHPMyAd
phpmyadmin使用什么语言
2024-04-08

Go语言中为什么要有GMP调度模型

今天小编给大家分享一下Go语言中为什么要有GMP调度模型的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。GMP调度模型是Go的
2023-07-06

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录