静态类型(statically typed)的语言,必须在编译期知道所有变量的类型
允许使用类型后缀来指定类型,例如 57u8
数字字面量还可以使用 _ 作为可视分隔符以方便读数,如 1_000
8 位 i8 u8
16 位 i16 u16
32 位 i32 u32
64 位 i64 u64
128 位 i128 u128
arch isize usize // 类似于go的int
十进制 98_222
十六进制 0xff
八进制 0o77
二进制 0b1111_0000
字节 (仅限于 u8) b'A'
使用 --release 参数进行发布(release)模式构建时,Rust 不检测会导致 panic 的整型溢出,Rust 会进行一种被称为二进制补码包裹(two’s complement wrapping)的操作,即u8的256变为0,u8的257变为1
显式处理溢出:
(1)使用 wrapping_* 方法在所有模式下进行包裹,例如 wrapping_add
(2)使用 checked_* 方法时发生溢出,则返回 None 值
(3)使用 overflowing_* 方法返回该值和一个指示是否存在溢出的布尔值
(4)使用 saturating_* 方法使值达到最小值或最大值
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 floored = 2 / 3; // Results in 0
// remainder
let remainder = 43 % 5;
}
sum = 15
difference = 91.2
product = 120
quotient = 1.7608695652173911
floored = 0
remainder = 3
Rust 的浮点型 f32 和 f64,它们的大小分别为 32 位和 64 位
默认浮点类型 f64,现代CPU 中它的速度与 f32 几乎相同,但精度更高
所有浮点型都有符号
浮点数按照 IEEE-754 标准表示
fn main() {
let x = 2.0; // f64
let y: f32 = 3.0; // f32
}
Rust布尔类型大小1B
fn main() {
let t = true;
let f: bool = false; // with explicit type annotation
}
char 字面量采用单引号括起来
字符串字面量用双引号括起来
Rust字符类型大小4B,表示的是一个 Unicode 标量值,可以表示远不止 ASCII。
标音字母,中文/日文/韩文的文字,emoji,还有零宽空格(zero width space)在 Rust 中都是合法的字符类型。
Unicode 值的范围为 U+0000 ~ U+D7FF 和 U+E000~U+10FFFF
fn main() {
let c = 'z';
let z = 'ℤ';
let heart_eyed_cat = '';
}
将多种类型的多个值组合到一个复合类型中
元组长度固定:声明后无法增长或缩小
没有任何值的元组 () ,只有一个值,
该类型被称为单元类型(unit type),该值被称为单元值(unit value)
如果表达式不返回任何其他值,就隐式地返回单元值
访问方式有通过.访问或者通过元组名称来访问
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;
let tup = (500, 6.4, 1);
let (x, y, z) = tup;
println!("The value of y is: {}", y);
}
满足如下任一条件时,数组有用
(1)将数据分配到栈(stack)而不是堆(heap)
(2)确保始终具有固定数量的元素
数组的初始化方式
let a = [3; 5];
let a: [i32; 5] = [1, 2, 3, 4, 5];
use std::io;
fn main() {
let a = [1, 2, 3, 4, 5];
println!("Please enter an array index.");
let mut index = String::new();
io::stdin()
.read_line(&mut index)
.expect("Failed to read line");
let index: usize = index
.trim()
.parse()
.expect("Index entered was not a number");
let element = a[index];
println!(
"The value of the element at index {} is: {}",
index, element
);
}
在索引操作中使用无效值时导致运行时(runtime)错误
程序退出并显示错误消息
函数体由一系列语句组成,也可选地以表达式结尾
注意这里的语句和表达式的区别
fn main() {
let x = plus_one(5);
println!("The value of x is: {}", x);
}
fn plus_one(x: i32) -> i32 {
x + 1 // 它是一个表达式,注意这里没有;
}
语句不返回值
fn main() {
let y = 6;
// let x = (let y = 6); // let y = 6 语句并不返回值,所以没有可以绑定到 x 上的值,报错
}
表达式可以在{}中
fn main() {
let y = {
let x = 3;
x + 1
};
println!("The value of y is: {}", y);
}
表达式也可以是数字
fn five() -> i32 {
5
}
let condition = true;
let number = if condition { 5 } else { 6 };
// 变量必须只有一个类型。Rust 需要在编译时就确切地知道 number 变量的类型
// let number = if condition { 5 } else { "six" }
// 报错,Rust 并不会尝试自动地将非布尔值转换为布尔值
let number = 3;
if number {
println!("number was three");
}
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结合标签跳出标签级别的循环
break 'counting_up;
}
remaining -= 1;
}
count += 1;
}
println!("End count = {}", count);
}
从循环返回表达式,注意不是语句
fn main() {
let mut counter = 0;
let result = loop {
counter += 1;
if counter == 10 {
break counter * 2;
}
};
println!("The result is {}", result);
}
fn main() {
// 循环
let mut number = 3;
while number != 0 {
println!("{}!", number);
number -= 1;
}
// 遍历数组
let a = [10, 20, 30, 40, 50];
let mut index = 0;
while index < 5 {
println!("the value is: {}", a[index]);
index += 1;
}
}
fn main() {
let a = [10, 20, 30, 40, 50];
for element in a {
println!("the value is: {}", element);
}
// rev() 用来反转区间,(1..4)生成1、2、3的序列
for number in (1..4).rev() {
println!("{}!", number);
}
}