Rust基础
简介
Rust是由Graydon Hoare于2009年发起的一门系统级、编译型编程语言,其设计准则为“安全,并发,实用”,支持函数式,并发式,过程式以及面向对象的编程风格。
特点
高性能: Rust 速度惊人且内存利用率极高。由于没有运行时和垃圾回收,它能够胜任对性能要求特别高的服务,可以在嵌入式设备上运行,还能轻松和其他语言集成。
可靠性: Rust 丰富的类型系统和所有权模型保证了内存安全和线程安全,让您在编译期就能够消除各种各样的错误。
生产力: Rust 拥有出色的文档、友好的编译器和清晰的错误提示信息, 还集成了一流的工具 —— 包管理器和构建工具, 智能地自动补全和类型检验的多编辑器支持, 以及自动格式化代码等等。
语言特性
所有权:
生命周期:
特性(trait):
enum:
异步语法:
所有权、引用/借用(Borrow/Reference)
每个
值
(内存)都绑定(通过let
)到一个变量
,该变量
拥有该值
(内存)所有权;let 是函数式语言中的绑定(binding),而不是赋值(assignment);
&'a T
是 Copy 的,需要的时候就会拷贝。&'a mut T
则不是,如果你用赋值的话,它会move。这就确保了&'a mut T
是一个noalias pointer,不但能够确保安全,还对优化有很大的帮助。
语法基础
循环
rust提供三种循环关键字:
for
:范围及迭代循环;while
:条件循环;loop
:无限循环;
rust循环内部控制关键字:
continue
:break
:
|
|
函数
|
|
模式匹配
模式匹配是 Rust 中借鉴函数式语言中的语法,用于为类型的解构提供一个方便的用法;
模式匹配常用在以下语句中:
match <value> { ... }
;if let
;while let
for
函数参数
...
默认
match
模式匹配会move被匹配的对象,在pattern
中使用ref
来获取被匹配对象的引用,来通过引用获取被匹配对象的所有权,避免所有权转移;相较于
&
作用于被匹配对象中,ref
匹配直接使用于pattern
中;
模式匹配位置
|
|
模式匹配语法
|
|
范围(Range)表达式
|
|
宏
- 定义:
macro_rules! macro_name { (pattern) => {do_something} }
- Rust 宏基于模式匹配;
- Rust 宏是卫生宏;
|
|
闭包(Colusure)
闭包是包含了外部变量的函数;
总共有3种类型的闭包:
Fn
:FnMut
FnOnce
闭包可以近似地理解为一个实现了FnOnce、FnMut和Fn其中一个trait的匿名结构体,这个匿名结构体保存捕获的环境中的变量。通过调用trait的方法来执行闭包体中的代码。
|
|
生命周期
Rust 中的每一个 引用 都有其生命周期,也就是引用保持有效的作用域;
生命周期的主要目标是避免悬垂引用,它会导致程序引用了并非其期望引用的数据;
生命周期注解告诉 Rust 多个引用的泛型生命周期参数如何相互联系;
如果函数有一个生命周期
'a
的i32
的引用的参数first
,还有另一个同样是生命周期'a
的i32
的引用的参数second
,这两个生命周期注解有相同的名称意味着first
和second
必须与这相同的泛型生命周期存在得一样久;
|
|
Trait(特性)
- trait(特征)类似于其他语言中的 interface 或者 protocol,指定一个实际类型必须满足的功能集合。
|
|
trait 与泛型
|
|
属性(attribute)
rust中的属性是一种元数据格式,应用于mod、crate 或项(item)的元数据(metadata)。可以用来:
- 条件编译代码
- 设置 crate 名称、版本和类型(二进制文件或库)
- 禁用 lint (警告)
- 启用编译器的特性(宏、全局导入(glob import)等)
- 链接到一个非 Rust 语言的库
- 标记函数作为单元测试
- 标记函数作为基准测试的某个部分
当属性作用于整个 crate 时,它们的语法为 #![crate_attribute]
;
当它们用于模块 或项时,语法为 #[item_attribute]
(注意少了感叹号 !
);
属性语法
属性语法形式如下:
|
|
属性可以接受参数,有不同的语法形式:
#[attribute = "value"]
#[attribute(key = "value")]
#[attribute(value)]
属性可以多个值,它们可以分开到多行中:
|
|
属性的分类
属性可以被分为以下四类:
常用属性
Test
test
属性用来把一个函数标记为单元测试函数,这些函数只有在测试模式下(cargo test
或rustc --test
)才会被编译。测试函数没有参数,并且返回值类型必须是以下两种:
- ()
- Result<(), E> where E: Error
示例:
|
|
Derive
derive
属性一般用来为数据类型生成 Trait 实现。
|
|
编译器会自动为 Foo
生成 PartialEq
的实现:
|
|
目前 derive
仅支持标准库中部分的 Trait,我们也可以通过 procedural macros
来为自己的 Trait 实现 derive
。其实,标准库里也是通过这种方式实现的,比如:Debug。