rust的基础部分,变量、常量、数据类型、函数、注释和控制流
变量与可变性
变量使用
let
关键字,默认不可变但在变量名之前加
mut
关键字来使其可变常量使用
const
关键字,并且必须注明值类型const MAX_POINTS: u32 = 100_000;
变量隐藏,重复使用
let
关键字来多次隐藏。当再次使用let
时,实际上创建了一个新变量,我们可以改变值的类型,但复用这个名字fn main(){ let x =5; let x = x + 1; let x = x * 2; println!("x值是:{}",x); // x值是:12 }
使用
mut
创建的变量,二次赋值必须是同类型
数据类型
标量类型
整数
长度 | 有符号 | 无符号 |
---|---|---|
8-bit | i8 | u8 |
16-bit | i16 | u16 |
32-bit | i32 | u32 |
64-bit | i64 | u64 |
arch | isize | usize |
每一个有符号的变体可以储存包含从 -(2^(n-1)) 到 2^(n-1)-1 在内的数字,这里 n 是变体使用的位数。所以
i8
可以储存从 -(2^(7)) 到 2^(7)-1 在内的数字,也就是从 -128 到 127。无符号的变体可以储存从 0 到 2^(n)-1 的数字,所以u8
可以储存从 0 到 2^(8)-1 的数字,也就是从 0 到 255。 另外,isize
和usize
类型依赖运行程序的计算机架构:64 位架构上它们是 64 位的, 32 位架构上它们是 32 位的。
Rust中的整型字面值
数字字面值 | 例子 |
---|---|
Decimal | 98_222 |
Hex | 0xff |
Octal | 0o77 |
Binary | 0b1111_0000 |
Byte(u8 only) | b'A' |
那么该使用哪种类型的数字呢?如果拿不定主意,Rust 的默认类型通常就很好,数字类型默认是 i32:它通常是最快的,甚至在 64 位系统上也是。isize 或 usize 主要作为某些集合的索引。
整型溢出
当在 debug 模式编译时,Rust 检查这类问题并使程序 panic,这个术语被 Rust 用来表明程序因错误而退出。
在 release 构建中,Rust 不检测溢出,相反会进行一种被称为 “two’s complement wrapping” 的操作。简而言之,256 变成 0,257 变成 1,依此类推。依赖溢出被认为是一种错误,即便可能出现这种行为。如果你确实需要这种行为,标准库中有一个类型显式提供此功能,Wrapping
。
浮点型
Rust 的浮点数类型是 f32
和 f64
,分别占 32 位和 64 位。默认类型是 f64
,因为在现代 CPU 中,它与 f32
速度几乎一样,不过精度更高。
布尔型
Rust 中的布尔类型有两个可能的值:true
和 false
。Rust 中的布尔类型使用 bool
表示。
字符类型
Rust 的 char
类型是语言中最原生的字母类型(注意 char
由单引号指定,不同于字符串使用双引号。)
符合类型
元组类型
fn main() {
let tup: (i32, f64, u8) = (500, 6.4, 1);
}
fn main() {
let tup = (500, 6.4, 1);
let (x, y, z) = tup;
println!("The value of y is: {}", y);
}
fn main() {
let x: (i32, f64, u8) = (500, 6.4, 1);
let five_hundred = x.0;
let six_point_four = x.1;
let one = x.2;
}
数组类型
与元组不同,数组中的每个元素的类型必须相同。Rust 中的数组是固定长度的:一旦声明,它们的长度不能增长或缩小。
fn main() {
let a = [1, 2, 3, 4, 5];
}
let a: [i32; 5] = [1, 2, 3, 4, 5];
fn main() {
let a = [1, 2, 3, 4, 5];
let first = a[0];
let second = a[1];
}
当访问数组越界,编译并不会产生任何错误,不过程序会出现一个运行时(runtime)错误并且不会成功退出。
函数
fn main() {
another_function(5, 6);
}
fn another_function(x: i32, y: i32) {
println!("The value of x is: {}", x);
println!("The value of y is: {}", y);
}
语句(Statements)是执行一些操作但不返回值的指令。表达式(Expressions)计算并产生一个值。
fn main() {
let x = 5;
let y = {
let x = 3;
x + 1
};
println!("The value of y is: {}", y);
// The value of y is: 4
}
具有返回值的函数
函数可以向调用它的代码返回值。我们并不对返回值命名,但要在箭头(->)后声明它的类型。在 Rust 中,函数的返回值等同于函数体最后一个表达式的值。使用 return 关键字和指定值,可从函数中提前返回;但大部分函数隐式的返回最后的表达式。
fn five() -> i32 {
5
}
fn main() {
let x = five();
println!("The value of x is: {}", x);
}
注释
只允许 //
这种写法。
控制流
if
表达式
fn main() {
let number = 3;
if number < 5 {
println!("condition was true");
} else {
println!("condition was false");
}
}
fn main() {
// 我们要判断 number 不为零
let number = 3;
// if 表达式只允许条件返回 bool 类型
// 这里改为 number != 0 才能编译通过
if number {
println!("number was three");
}
}
fn main() {
let number = 6;
if number % 4 == 0 {
println!("number is divisible by 4");
} else if number % 3 == 0 {
println!("number is divisible by 3");
} else if number % 2 == 0 {
println!("number is divisible by 2");
} else {
println!("number is not divisible by 4, 3, or 2");
}
}
在 let
语句中使用 if
fn main() {
let condition = true;
let number = if condition {
5
} else {
6
};
println!("The value of number is: {}", number);
// The value of number is: 5
}
在这种使用场景中,if
和 else
分支的值类型必须一致,不然编译会提示错误。
##使用循环重复执行
loop
fn main() {
let mut counter = 0;
let result = loop {
counter += 1;
if counter == 10 {
break counter * 2;
}
};
assert_eq!(result, 20);
}
while
当条件为真,执行循环。当条件不再为真,调用 break
停止循环。
fn main() {
let mut number = 3;
while number != 0 {
println!("{}!", number);
number = number - 1;
}
println!("LIFTOFF!!!");
}
for
fn main() {
let a = [10, 20, 30, 40, 50];
for element in a.iter() {
println!("the value is: {}", element);
}
}