编程基础
变量与可变性
在 rust 中声明变量按照以下的方式来声明:
let x = 100;
默认声明的变量是 immutable ,即不可变的。如果改变值的话会报错。
如果需要声明可变的变量,请加上 mut 关键字:
let mut x = 100;
x = 101;
常量
我们通常使用 const
来声明常量。
const MAX_POINT: u32 = 100_000;
常量和不可变的变量
区别:
- 常量使用 const 进行声明,类型必须被标注
- 常量可以在任何作用域内进行声明,包括全局作用域
- 常量只可以绑定到常量表达式
- 常量的命名规范:大写+下划线,例如:MAX_POINTS
Shadowing
中文叫做隐藏。
即可以使用相同的名字声明新的变量,新的变量就会 shadow 之前声明的同名变量。
let mut x = 5;
let x = x + 1;
在后序的代码中 x 代表的就是新的值。
使用 shadow 之后的效果:
- 类型可以和之前的类型不同
- 但是如果你不使用 shadow ,类型是需要匹配的
let mut x = 5;
x = "lijiajun";
改为以下就没有问题了:
let mut x = 5;
let x = "lijiajun";
数据类型
类型推断
由于 rust 是一门静态编译语言,所以它编译时需要知道所有的变量的类型。
- 基于所编写的代码,rust 一般可以推断出每一个变量的类型
- 但是如果推断出的类型较多,就需要我们自己标注
像下面这个例子,rust 可以推断出所有的数字类型,于是需要我们自己标注上 i32
来确定这个类型。
fn main() {
let guess: i32 = "3".parse().expect("Not a number!");
}
标量类型
一个标量类型代表一个单个的值。
Rust 有四个主要的标量类型:
- **整数:**没有小数部分,比如
u32
i32
最后的 arch 长度指的是由计算机的架构决定的,如果计算是 64 位的,那么就是 i64 和 u64,如果是 32 位的,以此类推。
注意:
- rust 的数值中可以使用下划线来分割表示。
- rust 的数值可以使用后缀表示类型:57u8
- 如果没有表示,默认的类型是 i32
整数溢出问题:
比如 u8
这个值的范围为 0 ~ 255,你给它赋值了 1000,之后再调试的时候,会导致程序 panic,即程序恐慌。
但是在发布的时候,是不会出错的,rust 会对这个溢出做环绕操作,即 256 表示 0, 257 表示 1 ,从头开始环绕,并不会出现 panic。
- 浮点数
分为单精度 f32
,和双精度 f64
两种。
其中 f64 为默认值。
- 布尔值
即 true 和 false,符号为 bool,大小为一个字节。
- 字符类型
即 char 类型,在 rust 中使用单引号,占据四个字节大小。
请看 rust 的推断:
我们可以看到 rust 中的字符类型远远比 unicode 中的要丰富,可以表示的更多。
数值操作
-
-
-
- /
- %
复合类型
- 元组:将多个类型的多个值放在一个类型中,长度无法修改。
fn main() {
let tup = (500, 6.4, 1);
// expect output: The value of x is: 6.4
println!("The value of y is: {}", tup.1)
}
也可以使用结构来获得值:
fn main() {
let tup = (500, 6.4, 1);
let (x, y, z) = tup;
println!("The value of y is: {}", x)
}
- 数组:将多个值放在一个类型里面,但是数组中的类型是必须要一样的,长度也不可变。
fn main() {
let arr = [1, 2, 3, 4, 5];
print!("{}", arr[0]);
}
数组的标注形式:
快捷方法,创建一个有重复元素的数组:
fn main() {
let arr = [3; 5];
print!("{}", arr[0]);
}
访问数组的元素越界:
- 编译时会检查,一些复杂情况下检查不出来,也不会报错
- 运行时会报错,rust 不允许越界访问。
变量
一些规定
声明函数使用 fn 来声明。
针对函数和变量名,rust 使用 snake 风格来书写,其实就是使用
_
的形式分割。
rust 中函数的声明式没有顺序的,与一些古早的语言不同,rust 可以在声明之前调用。
函数的参数
- param:形参,argument:实参,其实都是参数,知道就行。
- 在函数的签名中,必须声明每一个参数的类型
- 函数如果有返回值,必须指明返回值的类型
fn main() {
let mut res = sum(1, 2);
print!("sum: {}", res);
}
fn sum(a: i32, b: i32) -> i32 {
a + b
}
注意,在 rust 中,写在最后一行的值为返回值,不需要加上分号,如果加上分号意味着返回值为 ()
如果你想在最后一行之前返回,则需要使用 return 关键字。
fn main() {
let mut res = sum(1, 2);
print!("sum: {}", res);
}
fn sum(a: i32, b: i32) -> i32 {
return 10;
a + b
}
注释
// 这是注释
控制流
注意 if 后面的值必须是 bool 类型的,rust 不会帮你去转换的,只能使用布尔值。
fn main() {
let num = 5;
if num < 5 {
print!("condition was true");
} else {
print!("condition was false");
}
}
fn main() {
let num = if true { 5 } else { 6 };
if num < 5 {
print!("condition was true");
} else {
print!("condition was false");
}
}
循环
loop
fn main() {
let mut count = 1;
let result = loop {
println!("Hello, world!");
count += 1;
if count == 10 {
break count;
}
};
println!("result: {}", result);
}
while
fn main() {
let mut count = 3;
while count != 0 {
println!("{}", count);
count -= 1;
}
print!("Hello, Rust!");
}
for
用的最多。
fn main() {
let arr = [1, 2, 3, 4, 5];
for element in arr.iter() {
println!("{}", element)
}
}
fn main() {
let arr = (1..6).rev();
for element in arr {
println!("{}", element)
}
}