安装
www.rust-lang.org/zh-CN/tools…
在线运行
创建项目
cargo new hello_world // 创建项目
cargo run // 运行
更多细节,自行查找资料。
变量
1. 整形
整形变量包含多种范围的变量类型,如下:
类型 | 有符号 | 无符号 |
---|---|---|
8位 | i8 | u8 |
16位 | i16 | u16 |
32位 | i32 | u32 |
64位 | i64 | u64 |
128位 | i128 | u128 |
arch | isize | usize |
举例
fn main() {
let num: i8 = -1; // 有符号 整形
println!("i8 -> {}", num);
let num: String = "hello".to_string(); // 无符号 整形
println!("i8 -> {}", num);
}
存储范围公式
- 有符号
以 8位有符合存储类型 i8,进行存储类型计算,设 n = 8, 代入上方“公式”, 得出结果范围: -127 ~ 127
- 无符号
以 8位无符号存储类型 u8,进行存储类型计算,设 n = 8, 代入上方“公式”, 得出结果范围: 0 ~ 255
进制转换
Rust 中的 进制符号
0b:(B)二进制
- 0o:(O)八进制
- 0d:(D)十进制
- 0x:(H)十六进制
fn main() {
let num_hex: u8 = 0xff; // 16进制 -> 10 进制 自动类型转换
println!("0x to 0d -> {}", num_hex);
let num_octal: u8 = 0o77; // 8进制 -> 10 进制 自动类型转换
println!("0o to 0d -> {}", num_octal);
let num_binary: u8 = 0b111; // 2进制 -> 10进制 自动类型转换
println!("0b to 0d -> {}", num_binary);
let num_byte: u8 = b'A'; // Ascii 码 -> 10进制 自动类型转换
println!("Ascii码 to 0d -> {}", num_byte);
}
进制转换公式
2. 小数类型 - float 浮点
浮点类型 包含: f32 与 f64 两种类型;
fn main(){
let num: f32 = 1.2;
println!("f32 小数 -> {}", num);
let num: f64 = 12.2;
println!("f64 小数 -> {}", num);
let num = 12.2; // 如果不指定,默认是 f64 类型
println!("f64 小数 -> {}", num);
}
3. 逻辑类型 - bool 布尔
布尔类型 包含:true 与 false 两种结果,占用1个字节;
fn main() {
let t = true; // 自动推导为 bool 类型
let f: bool = false; // 指定为逻辑类型
}
4. 字节类型 - char
在 rust 中,字节类型 用 '' 单引号 包裹,并且占用4个字节,使用unicode表示,这样的好处是,可以表示的内容范围更多,
fn main() {
let z = 'z';
println!("char -> {}", z);
let z = 'ℤ';
println!("char -> {}", z);
let z = '😻';
println!("char -> {}", z);
}
复合类型
1. 元组类型
- 元组的长度是固定的:声明后,它们的大小就无法进行改变;
- 元组的下标以0开始计算,依次叠加1个步长 (和数组的计算方式一样);
- 元组可以包含多个不同的类型,以 “,” 分割;
fn main(){
let tup: (i32, f64, u8) = (500, 6.4, 1);
let (_, y, _) = tup; // 在解构元组类型时,可以 使用 _ 进行占位,
println!("元组 -> {}", y);
println!("元组 -> {}", tup.1); // 通过 元组.[下标] 进行 读取 元组 类型的 对应下标值
}
2. 数组类型
- 在Rust 中, 数组类型的长度是固定的,在声明之后,不可以进行改变;
fn main(){
let a: [i32; 5] = [1, 2, 3, 4, 5]; // 5个相同类型的 数组;
println!("数组 -> {}", a[0]);
let a = [1; 3]; // 3个相同数组元素的数组类型;
println!("数组 -> {}", a[0]);
}
额外收获
在定义数组类型时,可以使用 [i32;5] 的方式,定义一个支持5个相同类型长度的元素;此方式仅适用于数组类型;
在为数组类型赋值时,可以使用 [1;3] 的方式,创建3个都是元素1的数组类型;此方式仅适用于数组类型;
元组类型 与 数组类型的 区别
相同点
- 在声明类型后,类型的长度都不可以改变;
- 下标都是 从 0 开始;
不同点
- 元组类型 采用 () 括号包裹, 逗号 , 分割;
- 数组类型 采用 [] 方括号包裹,同时也是采用 , 逗号分割;
- 元组类型可以解构;
- 数组类型不支持解构;
- 元组类型 通过 (. 点)[下标]的形式访问值;
- 数组类型 通过 [下标]的形式访问值;
函数
语法规则
fn main() {
println!("这里是函数的天下");
fn_1();
fn_2(3);
fn_3(3, 100);
let num: i8 = fn_4();
println!("函数返回值 ->{}", num);
println!("有参数的函数返回值 ->{}", fn_5(1));
}
fn fn_1() {
println!("无参数的函数")
}
fn fn_2(x: i8) {
println!("只有一个参数的函数 -> {}", x);
}
fn fn_3(x: i8, y: i32) {
println!("N个参数的函数 -> ({} , {})", x, y);
}
fn fn_4() -> i8 {
5
}
fn fn_5(x: i8) -> i8 {
x + 5
}
表达式
在 Rust 中,表达式的 最后一行代码没有“;” 分号结尾,说明该行语句是带有返回句柄的赋值语句;如果加了分号就表示是一条语句,没有返回句柄。
fn main(){
let y = {
let x = 3;
x + 1
};
println!("The value of y is: {}", y);
}
控制语句
1. if语句
fn main() {
let flag: bool = true;
// 单判断分支
if flag {
println!("True");
} else {
println!("False");
}
let age: i32 = 18;
// 多判断分支
if age > 18 {
println!("大于18");
} else if age < 18 {
println!("小于18");
} else {
println!("等于18");
}
let condition = true;
// 类似 三目运算符, 分支出口的表达式类型必须一致
let number = if condition { 5 } else { 6 };
println!("The value of number is: {}", number);
}
2. loop 循环语句
fn main() {
let mut counter = 0;
let result = loop {
counter += 1;
if counter == 10 {
break counter * 2;
}
};
println!("The result is {}", result);
}
3. while 循环语句
fn main() {
let mut number = 3;
while number != 0 {
println!("{}!", number);
number -= 1;
}
println!("LIFTOFF!!!");
}
4. for 循环语句
fn main() {
let a = [10, 20, 30, 40, 50];
for element in a.iter() {
println!("the value is: {}", element);
}
}
mut 可变不可变类型
为什么Rust 中,存在不可变的类型?
在 javascript 弱类型语言中,不可变类型只有 const 定义的变量才具有不可变的作用,但是对于 class 的引用也只是 引用地址、基本类型的不可变,class 的属性 方法还是可以动态绑定,修改的。
在 Rust 中,定义一个不可变的变量,是不允许为此变量再次进行赋值的,如果想要赋值,只能是如下方式
let name = 'hello';
name = 'word'; // 错误, 不允许再次赋值, 因为是不可变量
let name = 'word'; // 正确, Shadowing - rust 特性,可以重复定义一个变量 去重新赋值
let name = 12; // 错误, 虽然rust 提供了重新定义变量赋值的思想,但是 起码需要给定一个 一致的类型,因为该 name 变量 在第一次定义时,已被确定为字符串类型,由于 (字符串 != 数字) 所以失败。
let name: u8 = 12; // 正确, 因为重新指定了变量的类型,虽然变量名还一样,但是类型已经发生改变,使得 “=” 两边的类型一致。
Rust 的可变类型?
可变类型就比较好理解了,指的是定义出来的变量可以被多次赋值,条件(类型一致)
let mut name = 'hello';
name = 'word'; // 正确, 因为该变量首次定义时,已被声明为可变类型的变量
name = 12; // 错误, 类型不一致, 搞毛啊
可变与不可变类型的区别?
在上面大致介绍了,Rust 中的可变与不可变类型,那么他们的区别其实也就是那么几点。
let mut name = 'hello'; // 可变类型
let age = 12; // 不可变类型
区别:可变类型需要使用 mut 修饰变量;相反 不可变类型不需要。
不可变类型 是否可以 重新赋值?
不可以重新赋值,但是我们可以采取 Rust 的 Shadowing 技术,我理解为是衍生变量。 可以在使用的地方再次定义相同变量名的变量进行赋值。
let name = 'hello';
/* ... 此处省略了无数行代码 ... */
let name = 'word';
常见问题
1. 出现 Blocking waiting for file lock on package cache
修复:rm -rf ~/.cargo/.package-cache
2. 替换镜像源
打开 /.cargo/config 文件
替换如下内容
[source.crates-io]
registry = "https://github.com/rust-lang/crates.io-index"
replace-with = 'ustc'
[source.ustc]
registry = "git://mirrors.ustc.edu.cn/crates.io-index"