广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >为什么要使用Rust语言、Rust语言有什么优势
  • 520
分享到

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

2024-04-02 19:04:59 520人浏览 薄情痞子
摘要

Rust 是一种采用过去的知识解决将来的问题的技术。” ——Graydon Hoare 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 语言优势内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: 为什么要使用Rust语言、Rust语言有什么优势

本文链接: https://www.lsjlt.com/news/169032.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

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

下载Word文档
猜你喜欢
  • 为什么要使用Rust语言、Rust语言有什么优势
    Rust 是一种采用过去的知识解决将来的问题的技术。” ——Graydon Hoare Rust 是一种快速、高并发、安全且具有授权性的编程语言,...
    99+
    2022-11-13
  • Rust语言技巧的使用方法是什么
    这篇文章主要介绍“Rust语言技巧的使用方法是什么”,在日常操作中,相信很多人在Rust语言技巧的使用方法是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Rust语言技巧的使用方法是什么”的疑惑有所帮助!...
    99+
    2023-06-16
  • 为什么go和rust语言都舍弃了继承
    一、继承 1、什么是继承 继承是一种面向对象编程的重要特性,它可以让子类继承父类的属性和方法,并在此基础上进行扩展。 2、继承的问题 继承层次复杂:当类之间存在多层继承关系时,会形成复杂的继承层次,难以维护和理解。 ...
    99+
    2023-10-29
    语言 rust
  • C++语言有什么优势
    这篇文章主要讲解了“C++语言有什么优势”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“C++语言有什么优势”吧!入门简介    C++是个强大的语言,可以用于做别的语言做不了的工作。但是,这...
    99+
    2023-06-17
  • 怎么使用Rust语言的类型转换
    本篇内容介绍了“怎么使用Rust语言的类型转换”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!什么是类型转换类型转换,是调用函数时,根据函数要...
    99+
    2023-06-16
  • 对比 Go 语言,Kotlin 有什么优势和劣势
    一、更简洁灵活 Kotlin 是多范式语言,对泛型和函数式编程有良好支持,可以写出更简洁和灵活的代码;Go 对泛型支持很弱,甚至可以说不支持,需要使用接口或反射来实现一些通用的功能。 二、支持多平台 Kotlin 支持多平...
    99+
    2023-10-29
    有什么 劣势 优势
  • go语言的优势和劣势是什么
    这篇“go语言的优势和劣势是什么”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“go语言的优势和劣势是什么”文章吧。go语言的...
    99+
    2023-07-04
  • JavaScript语言有什么优点
    这篇文章主要介绍“JavaScript语言有什么优点”,在日常操作中,相信很多人在JavaScript语言有什么优点问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”JavaSc...
    99+
    2022-10-19
  • Java语言有什么优点
    本篇内容介绍了“Java语言有什么优点”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!  Java是一门全球范围内使用最广泛的,面向对象的编程...
    99+
    2023-06-02
  • go语言的用途是什么及有哪些优势
    这篇文章主要介绍“go语言的用途是什么及有哪些优势”,在日常操作中,相信很多人在go语言的用途是什么及有哪些优势问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”go语言的用途是什么及有哪些优势”的疑惑有所帮助!...
    99+
    2023-07-04
  • 为什么要将JS语言转成Go语言?多方面探讨
    如今,javascript(JS)作为一种通用的编程语言在前端开发中扮演着极其重要的角色,但是在服务端开发中,Golang(Go)也同样广受欢迎。那么,为什么要考虑将JS语言转换成Go语言呢?本文将从以下几个方面探讨这个问题。1.性能方面J...
    99+
    2023-05-14
  • Go语言中为什么要有GMP调度模型
    今天小编给大家分享一下Go语言中为什么要有GMP调度模型的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。GMP调度模型是Go的...
    99+
    2023-07-06
  • VB.NET语言有什么用
    这篇文章主要介绍了VB.NET语言有什么用,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。我使用VB.NET的时间越长,我就越是欣赏VB.NET语言和结构。作为一名VB程序员,...
    99+
    2023-06-17
  • Kotlin语言有什么用
    这篇文章主要为大家展示了“Kotlin语言有什么用”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Kotlin语言有什么用”这篇文章吧。Kotlin 是一种在 Java 虚拟机上运行的静态类型编程...
    99+
    2023-06-27
  • 为什么要使用Go语言进行并发编程?
    随着计算机技术的不断进步,人们对并发编程的需求也越来越高。并发编程是指同时执行多个任务的能力,其优点是可以提高程序的性能和响应速度。在传统的编程语言中,如C++和Java,实现并发编程需要使用线程和锁等复杂的机制。而Go语言则提供了一种更...
    99+
    2023-07-27
    同步 并发 日志
  • Go 语言的 Shell 容器:是什么,如何使用,有何优势?
    随着云计算和容器化技术的发展,容器已经成为了现代应用程序开发、部署和运行的标准方式。在这个领域中,Docker 可能是最知名的容器化技术之一。然而,Docker 并不是唯一的容器化技术,也并不一定适用于所有的场景。Go 语言的 Shell...
    99+
    2023-07-29
    shell 容器 并发
  • 处理大数据日志,Go语言有什么优势?
    大数据时代已经来临,每天都会产生大量的数据,其中包括了日志数据。如何处理这些海量的日志数据,已经成为了当前互联网公司所面临的一个重要问题。在这个问题上,Go语言应运而生,它的高并发、高效率、简洁明了的语法使得它成为了处理大数据日志的一种优...
    99+
    2023-09-01
    大数据 日志 打包
  • 编程领域内为什么要有那么多的语言
    一、多样的需求 不同的应用场景和问题可能需要不同的编程语言来解决。例如,Web开发领域可以使用JavaScript,科学计算可以使用Python,系统级编程可以使用C/C++,移动应用可以使用Java或Kotlin等。每种语言都有其擅长的领...
    99+
    2023-10-29
    要有 那么多 域内
  • Java、C、PHP、Python语言主要有什么用
    这篇文章给大家分享的是有关Java、C、PHP、Python语言主要有什么用的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。Javajava常常跟”企业”联系在一起, 因为具备一些很好的语言特性, 以及丰富的框架,...
    99+
    2023-06-04
  • Python编程语言使用中有什么优点
    这篇文章主要介绍“Python编程语言使用中有什么优点”,在日常操作中,相信很多人在Python编程语言使用中有什么优点问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Python编程语言使用中有什么优点”的疑...
    99+
    2023-06-17
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作