Rust的设计思想和代码示例
【摘要】 Rust是一种多范式编程语言,专注于性能和安全,尤其是安全并发,Rust在语法上类似于C++,但提供了确保内存安全的功能,它不使用垃圾收集机制。 Rust最初是由Mozilla Research的Graydon Hoare设计的,Dave Herman、Brendan Eich等人也做出了贡献。 设计者们在编写Servo布局和Rust编译器的同时,对该语言进行了改进。Rust编译器是免费的开...
Rust是一种多范式编程语言,专注于性能和安全,尤其是安全并发,Rust在语法上类似于C++,但提供了确保内存安全的功能,它不使用垃圾收集机制。
Rust最初是由Mozilla Research的Graydon Hoare设计的,Dave Herman、Brendan Eich等人也做出了贡献。
设计者们在编写Servo布局和Rust编译器的同时,对该语言进行了改进。Rust编译器是免费的开源软件,采用MIT License和Apache License 2.0双重授权。
自2016年以来,Rust在Stack Overflow开发者调查中每年都是 "最受欢迎的编程语言"。
1 设计
Rust旨在成为一种高并发和高安全的编程语言,能够支持大系统编程,即创建和维护能保持大系统完整性的边界,这就要求着门语言要着重强调安全、控制内存布局和并发的特性。
1.1 Rust众所周知的性能
Rust的性能与C++的性能相当。
1.2 语法
Rust的具体语法与C和C++类似,代码块由大括号分隔,控制流关键字也使用如if、else、while和for。
然而,并不是所有的C或C++关键字都能在Rust中使用,一些Rust函数(如使用关键字match进行模式匹配)对于那些熟悉出C/C++语言的人来说会不太熟悉。
尽管表面上与C和C++相似,但从更深层的意义上来说,Rust的语法更接近于ML语言家族和Haskell语言的语法。
Rust函数体的几乎每一个部分都是表达式,甚至是控制流操作符。例如,普通的if表达式也取代了C语言的三元条件。和Lisp中一样,一个函数不需要以返回表达式结束:在这种情况下,如果省略分号,函数中的最后一个表达式就会产生返回值。
1.3 内存安全
Rust被设计为内存安全,因此它不允许在安全代码中出现空指针、悬空指针或数据竞赛。
数据值只能通过一组固定的形式进行初始化,所有这些形式都要求变量必须初始化。 为了提供类似在其他语言中判断指针是否有效的或NULL的功能,如在链接列表或二进制树数据结构中的指针,Rust核心库提供了一个选项类型,可以用来测试指针是否具有Some值或None。
Rust还引入了附加的语法来管理变量寿命,编译器通过它的借用检查器来说明这些原因。如果想使用一些不安全的代码,可以使用unsafe关键字来编写一些代码,一般不建议这么做。
1.4 内存管理
Rust不使用像Go、Java或.NET框架所使用的自动垃圾收集系统,也不使用Swift和Objective-C等语言所使用的自动引用计数。相反地,内存和其他资源是通过资源获取即初始化(RAII)约定来管理的,并有可选的引用计数。
Rust提供了资源的确定性管理,开销非常低。
Rust还倾向于值的堆栈分配,并且不执行隐式装箱。
Rust还有一个引用的概念(使用&符号),它不涉及运行时引用计数。使用这种指针的安全性在编译时由借用检查器验证,防止悬空指针和其他形式的未定义行为。
1.5 所有权
Rust有一个所有权系统,所有的值都有一个唯一的所有者,值的范围和所有者的范围是一样的,值可以:
l 通过不可变引用,使用&T;
l 通过可变引用,使用&mut T;
l 或者通过值,使用T
来传递,在任何时候,都可以有多个不可变引用或者一个可变引用(隐式的读者-作者锁)。Rust编译器在编译时强制执行这些规则,也会检查所有引用是否有效。
1.6 类型和多态性
类型系统支持一种类似于类型类的机制,称为 "特质",这是直接受Haskell语言的启发而来的。这是一种通过在类型变量声明中添加约束条件来实现临时多态性的措施。
其他来自Haskell的功能,如更高的多态性,还没有得到支持。
Rust 的特点是对用关键字 let 声明的变量进行类型推理。这样的变量不需要初始赋值来确定其类型,如果任何代码分支没有给变量赋值,就会产生编译时错误。多次赋值的变量必须用关键字mut标记。
函数可以被赋予通用参数,这些参数通常需要通用类型来实现某个或某些特质。在这样的函数中,泛型值只能通过这些特质来使用。这意味着,一个通用函数在定义后就可以进行类型检查。
这与C++模板不同,C++模板从根本上说是鸭型的,在用具体类型实例化之前不能进行类型检查。
然而,Rust泛型的实现类似于C++模板的典型实现:为每个实例化生成一个单独的代码副本。这就是所谓的单态化,与Java和Haskell中典型的类型擦除方案形成鲜明对比。单态化的好处是为每个特定的用例优化了代码;缺点是增加了编译时间和生成的二进制文件的大小。
Rust的对象系统基于实现、特征和结构化类型。实现的作用类似于其他语言中的类,用关键字 impl 来定义。特征提供了继承和多态性;它们允许定义方法并将其混合到实现中。结构化类型被用来定义字段,实现和traits不能自己定义字段,只有traits能提供继承。这防止了像C++中的多重继承可能造成的钻石继承问题。
换句话说,Rust支持接口继承,但用composition取代了实现继承。
2 代码示例
2.1 你好世界
用Rust编写的简单的 "你好,世界!"程序。println!宏将信息打印到标准输出。
fn main() {
println!("Hello World!");
}
2.2 因子函数
2.2.1 递归式
fn factorial(i: u64) -> u64 {
match i {
0 => 1,
n => n * factorial(n-1)
}
}
2.2.2 迭代
fn factorial(i: u64) -> u64 {
let mut acc = 1;
for num in 2..=i {
acc *= num;
}
acc
}
2.2.3 使用迭代器
fn factorial(i: u64) -> u64 {
(1..=i).product()
}
3 新版本
Rust团队发布了Rust的新版本1.44.0。
Rust 1.44是一个小版本,Cargo集成了Cargo树功能,在no_std上下文中支持async/await。
4 参考
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
作者其他文章
评论(0)