特性
Rust致力于成为优雅解决高并发和高安全性系统问题的编程语言 [18] ,适用于大型场景,即创造维护能够保持大型系统完整的边界。这就导致了它强调安全,内存布局控制和并发的特点。标准Rust性能与标准C++性能不相上下。
环境安装
在 Linux 或 mac 上安装 rustup
打开终端并输入如下命令:
$ curl --proto '=https' --tlsv1.2 https://sh.rustup.rs -sSf | sh
此命令下载一个脚本并开始安装 rustup
工具,这会安装最新稳定版Rust
。过程中可能会提示你输入密码。如果安装成功,将会出现如下内容:
Rust is installed now. Great!
更新和卸载
通过 rustup 安装了 Rust 之后,很容易更新到最新版本。在 shell 中运行如下更新脚本:
$ rustup update
为了卸载 Rust 和 rustup,在 shell 中运行如下卸载脚本:
$ rustup self uninstall
检查是否正确安装了 Rust
打终端并运行如下行:
$ rustc --version
rustc x.y.z (abcabcabc yyyy-mm-dd)
cargo --version
cargo 1.57.0 (b2e52d7ca 2021-10-21)
你应能看到已发布的最新稳定版的版本号、提交哈希和提交日期,显示为如下格式:如果出现这些内容,Rust 就安装成功了!Cargo 是 Rust 的构建系统和包管理器 比如构建代码、下载依赖库并编译这些依赖,官方安装包自带了 Cargo
,所以上面的执行cargo --version
是可以正常输出的
Hello, world
使用cargo新建项目,会在当前目前生成一个project
cargo new hello_cargo
- Cargo.toml
类似
go.mod
,pom.xml
依赖管理文件 - src
存放源代码
- target
编译产物
- Cargo.lock
用来存放对依赖的变更,类似
go.sum
常用的命令
编译
cargo build
运行
cargo run
检查代码确保其可以编译
cargo check
关键字
- as - 强制类型转换,消除特定包含项的 trait 的歧义,或者对 use 和 extern crate 语句中的项重命名
- break - 立刻退出循环
- const - 定义常量或不变裸指针(constant raw pointer)
- continue - 继续进入下一次循环迭代
- crate - 链接(link)一个外部 crate 或一个代表宏定义的 crate 的宏变量
- dyn - 动态分发 trait 对象
- else - 作为 if 和 if let 控制流结构的 fallback
- enum - 定义一个枚举
- extern - 链接一个外部 crate 、函数或变量
- false - 布尔字面值 false
- fn - 定义一个函数或 函数指针类型 (function pointer type)
- for - 遍历一个迭代器或实现一个 trait 或者指定一个更高级的生命周期
- if - 基于条件表达式的结果分支
- impl - 实现自有或 trait 功能
- in - for 循环语法的一部分
- let - 绑定一个变量
- loop - 无条件循环
- match - 模式匹配
- mod - 定义一个模块
- move - 使闭包获取其所捕获项的所有权
- mut - 表示引用、裸指针或模式绑定的可变性
- pub - 表示结构体字段、impl 块或模块的公有可见性
- ref - 通过引用绑定
- return - 从函数中返回
- Self - 实现 trait 的类型的类型别名
- self - 表示方法本身或当前模块
- static - 表示全局变量或在整个程序执行期间保持其生命周期
- struct - 定义一个结构体
- super - 表示当前模块的父模块
- trait - 定义一个 trait
- true - 布尔字面值 true
- type - 定义一个类型别名或关联类型
- unsafe - 表示不安全的代码、函数、trait 或实现
- use - 引入外部空间的符号
- where - 表示一个约束类型的从句
- while - 基于一个表达式的结果判断是否进行循环
保留做将来使用的关键字
如下关键字没有任何功能,不过由 Rust 保留以备将来的应用。
- abstract
- async
- await
- become
- box
- do
- final
- macro
- override
- priv
- try
- typeof
- unsized
- virtual
- yield
变量
在Rust中变量默认不可变(immutale),当变量不可变之后一单值绑定到一个名称上,就无法使用赋值语句来修改,只能使用关键字mut
来,把不可变变量变成可变变量,使用大型数据结构时,适当地使用可变变量,可能比复制和返回新分配的实例更快。对于较小的数据结构,总是创建新实例,采用更偏向函数式的编程风格,可能会使代码更易理解,为可读性而牺牲性能或许是值得的。同时也可以使用let来定义一个同名变量把第一个变量覆盖。
标量类型
scalar类型代表一个单独的值。Rust 有四种基本的标量类型:整型、浮点型、布尔类型和字符类型
整型
长度 | 有符号 | 无符号 |
---|---|---|
8-bit | i8 | u8 |
16-bit | i16 | u16 |
32-bit | i32 | u32 |
64-bit | i64 | u64 |
128-bit | i128 | u128 |
arch | isize | usize |
浮点型
f32
和 f64
,分别占 32
位和 64
位。默认类型是 f64
。
布尔型
bool
和golang
一样
字符类型
char
和golang
一样
复合类型
Rust 有两个原生的复合类型:元组(tuple
)和数组(array
),元组不要求每个元素的数据类型一致。Rust的数组和Java的数组一样,长度是固定的。
默认的formater
无法直接打印元组 使用println!("this tuple is {:?}",tup)
来打印元组;访问元组内的数据,使用.
来按照下标序号处理从0开始。例如tup.0
代表输出元组tup的第一个元素。
函数
Rust
中的函数 关键字是fn
,用来声明一个新函数,通过输入 fn 后面跟着函数名和一对圆括号来定义函数。大括号告诉编译器哪里是函数体的开始和结尾。(比go都少2字母!)太省略了,Rust
代码中的函数和变量名使用 snake case
规范风格。在 snake case
中,所有字母都是小写并使用下划线分隔单词,Rust的参数变量和类型中间增加了:
顺序和Go一致,都是变量在前,类型在后,Java则是类型在前,变量在后;
fn main() {
print_labeled_measurement(5, 'h');
}
fn print_labeled_measurement(value: i32, unit_label: char) {
println!("The measurement is: {}{}", value, unit_label);
}
表达式
赋值语句不含有返回值,在Rust中不支持x=y=6
这样的写法,在Rust中,大部分的代码都是表达式组成的,表达式是语句的一部分,如 let y=3;
,3
就是一个特殊的表达式 常量赋值表达式,代码语句块也是一个表达式,如
fn main(){
let y=1;
let x= {
let y=2;
y+2
};
}
//output y=1,x=4
声明一个Rust函数。开局的main函数是无参的,对于有返回值使用箭头来处理返回值(->)
不用对返回值命名,只需要指定类型 如
fn five() -> i32{
5
}
这函数与如下代码相同:
let x = 5;
细心的您,可能会发现five函数体中并没有代表语句结束的分号,那么是应为5就是一个表达式。如果我们对其增加分号,则表明这是一条语句,而语句则是没有返回值的,编译则会报错哟提示error[E0308]: mismatched types
fn five(x :i32) -> i32{
x+5;
}
cargo run
Compiling hello_cargo v0.1.0 (/Users/bytedance/rust_learning/project/hello_cargo)
error[E0308]: mismatched types
--> src/main.rs:12:20
|
12 | fn five(x :i32) -> i32{
| ---- ^^^ expected `i32`, found `()`
| |
| implicitly returns `()` as its body has no tail or `return` expression
13 | x+3;
| - help: consider removing this semicolon
For more information about this error, try `rustc --explain E0308`.
error: could not compile `hello_cargo` due to previous error
控制流
Rust 使用if ,else, else if
来进行分支控制处理,使用Loop来处理循环,在嵌套循环中,break 和 continue 应用于此时最内层的循环。你可以选择在一个循环上指定一个 循环标签(loop label),然后将标签与 break 或 continue 一起使用,使这些关键字应用于已标记的循环而不是最内层的循环
fn main() {
let mut count = 0;
'counting_up: loop {
println!("count = {}", count);
let mut remaining = 10;
loop {
println!("remaining = {}", remaining);
if remaining == 9 {
break;
}
if count == 2 {
break 'counting_up;
}
remaining -= 1;
}
count += 1;
}
println!("End count = {}", count);
}
小憩一下
- 第 N 个泰波那契数
泰波那契序列 Tn 定义如下:
T0 = 0, T1 = 1, T2 = 1, 且在 n >= 0 的条件下 Tn+3 = Tn + Tn+1 + Tn+2
给你整数 n,请返回第 n 个泰波那契数 Tn 的值。
impl Solution {
pub fn tribonacci(n: i32) -> i32 {
match n {
0|1=>n,
2=>1,
_=>{
let (mut x,mut y,mut z,mut c)=(0,1,1,2);
for _i in 3..=n{
c=x+y+z;
x=y;
y=z;
z=c
}
c
},
}
}
}