变量-数据类型
在rust中,变量默认是不可变的
let x = 5; //创建一个变量
x = 6;//报错
//解决 关键字 mut
let mut x = 5;
x=6;
变量隐藏
//rust中,定义变量后,可以定义一个与之前变量同名的新变量,但是第一个变量被第二个变量隐藏,之后读取的值是第二个变量的值
let x = 5;
let x = x + 1;
{
let x = x * 2;
//此时x的值为12,离开作用域后值无效
}
//此时x的值为6
常量
//声明常量
const THREE_HOURS_IN_SECONDS: u32 = 60 * 60 * 3;
数据类型
标量类型
标量(scalar)类型代表一个单独的值。Rust 有四种基本的标量类型:整型、浮点型、布尔类型和字符类型。
整型 (整数 是一个没有小数部分的数字。)
rust中的整形
长度 | 有符号 | 无符号 |
---|---|---|
8-bit | i8 | u8 |
16-bit | i16 | u16 |
32-bit | i32 | u32 |
64-bit | i64 | u64 |
128-bit | i128 | u128 |
arch | isize | usize |
每一个变体都可以是有符号或无符号的,并有一个明确的大小。有符号 和 无符号 代表数字能否为负值,换句话说,这个数字是否有可能是负数(有符号数),或者永远为正而不需要符号(无符号数)。这有点像在纸上书写数字:当需要考虑符号的时候,数字以加号或减号作为前缀;然而,可以安全地假设为正数时,加号前缀通常省略。有符号数以补码形式(two’s complement representation) 存储。
每一个有符号的变体可以储存包含从 -(2n - 1) 到 2n - 1 - 1 在内的数字,这里 n 是变体使用的位数。所以
i8
可以储存从 -(27) 到 27 - 1 在内的数字,也就是从 -128 到 127。无符号的变体可以储存从 0 到 2n - 1 的数字,所以u8
可以储存从 0 到 28 - 1 的数字,也就是从 0 到 255。另外,
isize
和usize
类型依赖运行程序的计算机架构:64 位架构上它们是 64 位的,32 位架构上它们是 32 位的。可以使用表格 3-2 中的任何一种形式编写数字字面值。请注意可以是多种数字类型的数字字面值允许使用类型后缀,例如
57u8
来指定类型,同时也允许使用_
做为分隔符以方便读数,例如1_000
,它的值与你指定的1000
相同。
rust整型字面值
数字字面值 | 例子 |
---|---|
Decimal (十进制) | 98_222 |
Hex (十六进制) | 0xff |
Octal (八进制) | 0o77 |
Binary (二进制) | 0b1111_0000 |
Byte (单字节字符)(仅限于u8 ) | b'A' |
整型溢出
比方说有一个 u8
,它可以存放从零到 255
的值。那么当你将其修改为 256
时会发生什么呢?这被称为 “整型溢出”(“integer overflow” ),这会导致以下两种行为之一的发生。当在 debug 模式编译时,Rust 检查这类问题并使程序 panic,这个术语被 Rust 用来表明程序因错误而退出。
使用 --release
flag 在 release 模式中构建时,Rust 不会检测会导致 panic 的整型溢出。相反发生整型溢出时,Rust 会进行一种被称为二进制补码 wrapping(two’s complement wrapping)的操作。简而言之,比此类型能容纳最大值还大的值会回绕到最小值,值 256
变成 0
,值 257
变成 1
,依此类推。程序不会 panic,不过变量可能也不会是你所期望的值。依赖整型溢出 wrapping 的行为被认为是一种错误。
为了显式地处理溢出的可能性,可以使用这几类标准库提供的原始数字类型方法:
- 所有模式下都可以使用
wrapping_*
方法进行 wrapping,如wrapping_add
- 如果
checked_*
方法出现溢出,则返回None
值 - 用
overflowing_*
方法返回值和一个布尔值,表示是否出现溢出 - 用
saturating_*
方法在值的最小值或最大值处进行饱和处理
浮点型
Rust 也有两个原生的浮点数类型,它们是带小数点的数字。Rust 的浮点数类型是
f32和
f64,分别占 32 位和 64 位。默认类型是
f64,因为在现代 CPU 中,它与
f32 速度几乎一样,不过精度更高。所有的浮点型都是有符号的
fn main() {
let x = 2.0; // f64
let y: f32 = 3.0; // f32
}
数值运算
Rust 中的所有数字类型都支持基本数学运算:加法、减法、乘法、除法和取余。整数除法会向零舍入到最接近的整数
fn main() {
// addition
let sum = 5 + 10;
// subtraction
let difference = 95.5 - 4.3;
// multiplication
let product = 4 * 30;
// division
let quotient = 56.7 / 32.2;
let truncated = -5 / 3; // 结果为 -1
// remainder
let remainder = 43 % 5;
}
布尔型
fn main() {
let t = true;
let f: bool = false;
}
字符串
fn main() {
let c = 'z';
let z: char = 'ℤ'; // with explicit type annotation
let heart_eyed_cat = '????';
}
复合类型
元组类型
元组是一个将多个其他类型的值组合进一个复合类型的主要方式。元组长度固定:一旦声明,其长度不会增大或缩小
fn main() {
let tup: (i32, f64, u8) = (500, 6.4, 1);
let tup2 = (500, 6.4, 1);
//读取
let (x, y, z) = tup2;
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 中的数组与一些其他语言中的数组不同,Rust 中的数组长度是固定的
fn main() {
let a = [1, 2, 3, 4, 5];
let first = a[0];
let second = a[1];
let a2: [i32; 5] = [1, 2, 3, 4, 5];
//变量名为 a3 的数组将包含 5 个元素,这些元素的值最初都将被设置为 3。这种写法与 let a3 = [3, 3, 3, 3, 3]; 效果相同,但更简洁
let a3 = [3; 5];
}