本节内容比较多,但也比较容易理解
主要包括:变量和可变性、数据类型、函数、注释、控制流
就不分成三章了,一篇讲完,每一部分
原文:Rust 程序设计语言
fn main() {
//
// 3.1 变量和可变性
//
// 基本类型
let a = 1; // 变量(不可变)
let mut b = 2; // 变量(可变)
const THREE_HOURS_IN_SECONDS: u32 = 60 * 60 * 3; // 常量
// 遮蔽
let x = 5;
let x = x + 1; // 遮蔽(shadow)
{
let x = x * 2;
println!("The value of x in the inner scope is : {}", x);
}
println!("The value of x is: {}", x);
// 不可遮蔽
// let mut x1 = 5;
// let x1 = x1 + 1; // 非法的遮蔽
let mut y = 6; // 变量(可变)
y = y + 1;
println!("The value of y is : {}", y);
// 变量类型不可变
// let mut spaces = " ";
// spaces = paces.len(); // 不允许修改变量的类型
// 遮蔽类型可变
let spaces1 = " ";
let spaces1 = spaces1.len();
println!("the value of spaces1 is {}", spaces1);
//
// 3.2 数据类型(静态类型)
//
// 3.2.1 标量类型(整型、浮点型、布尔型、字符)
// 整型
let no_guess = 42 // 不需要显式声明的整型
let guess: u32 = "42".parse().expect("Not a number!"); // 需要显式声明的整型
// 浮点型
let x = 2.0; // f64
let y: f32 = 3.0; // f32
// 布尔型
let t = true;
let f: bool = false;
// 字符类型(char,不是字符串)
let c = 'z';
let z = '?';
let heart_eyed_cat = '😻';
// 3.2.2 复合类型(元组类型、数组类型)
// 元组类型
// 解构取值
let tup = (500, 6.4, 1);
let (x, y, z) = tup;
let x: (i32, f64, u8) = (500, 6.4, 1);
// .取值
let tup: (i32, f64, u8) = (500, 6.4, 1);
let five_hundred = x.0;
let six_point_four = x.1;
let one = x.2;
// 数组类型
let months = ["January", "February", "March", "April", "May", "June", "July",
"August", "September", "October", "November", "December"];
let a: [i32; 5] = [1, 2, 3, 4, 5];
let a = [3; 5];
}
1、变量,默认是不可变的不能二次赋值,但你也可以选择让他可变,只要添加mut
,但数据类型不可变。
2、常量,是不允许更改的值,与其他语言相似。
3、遮蔽,可以通过声明和前面变量有相同名字的变量来遮蔽前面的变量。
注意:a、不能遮蔽可变的变量,b、遮蔽后的新变量仍应是一个不可变的变量,c、遮蔽后的新变量可以与前一个变量拥有不同的数据类型。
1、Rust是静态类型,必须在编译阶段能够确定出变量的类型。
2、标量类型:整型、浮点型、布尔型、字型;复合类型:元组、数组。
3、整型,数字字面量可以使用_
作为可视分隔符方便读书,类似1_000
4、整型,要当心整型溢出。
5、数字运算,整数除法会向下取整。
6、字符,用''
括起来,与字符串不同,大小为4个字节,是一个unicode标量值,所以可表示的远不止ASCII。
7、元组,每个位置类型可以不同。
8、元组,可以通过解构、.
来进行取值。
9、元组,没有任何值的元组()
被称为单元类型,值被称为单元值,表达式无返回值会隐式返回单元值,后面“2函数”部分也会提到。
10、数组,数组每个元素必须具有相同类型。
11、数组,与其他语言不通,长度是固定的。
12、数组,长度可变的是vector
,向量,也被称为“动态数组、可变数组”。
13、数组,访问时发生越界会导致运行时错误,程序直接退出。
1、字符的概念,会在后文展开。
2、vector
,会在后文展开。
fn main() {
// 函数:参数
another_function(5);
print_labeled_measurement(5, 'h');
// 语句与表达式
// let x = (let y = 6); // 不能用语句给语句赋值,要用表达式给语句赋值
let y = {
let x = 3;
x + 1 // 没有分号
};
println!("The value of y is: {}", y);
// 函数:返回值
let x = five();
println!("The value of x is: {}", x);
// 函数:参数、返回值
let x = plus_one(5);
println!("The value of x is: {}", x);
}
// 函数:单参数
fn another_function(x: i32) {
println!("The value of x is: {}", x);
}
// 函数:多参数
fn print_labeled_measurement(value: i32, unit_label: char) {
println!("The measurement is: {}{}", value, unit_label);
}
// 函数:返回值
fn five() -> i32 {
5
}
// 函数:参数、返回值
fn plus_one(x: i32) -> i32 {
x + 1 // 如果在末尾加上';'无返回值,则返回单元类型‘()’,会产生错误
}
1、代码风格,函数、变量名采用下划线命名法规范风格。
2、函数,可以定义在main之前或之后都可以。
3、函数,使用参数需要明确数据类型。
4、语句,是没有返回值的,一般以;
结尾。
5、表达式,是有返回值的,一般没有;
结尾。
6、函数,以表达式方式添加返回值,且需要明确返回值的数据类型。
7、函数,返回值与接收返回值的变量的数据类型需要一致。
1、代码中请使用//
。
2、文档注释使用///
,但一般并不使用。
3、编译器不会报错,但请不要使用/** */
暂无补充
fn main() {
//
// 条件 if
//
// if
let number = 3;
if number < 5 {
println!("condition was true");
} else {
println!("condition was false");
}
// if 类型需要严格匹配
// if number {
// println!("number was three");
// }
// if 与 let
let condition = true;
let number = if condition { 5 } else { 6 }; // 返回值,需要是同样类型
// let number = if condition { 5 } else { "six" }; // 返回值,不能是不同类型
println!("The value of number is: {}", number);
//
// 循环 loop、while、for
//
// loop
// loop 退出方式
let mut count = 0;
'counting_up: loop { // 标签counting_up
println!("count = {}", count);
let mut remaining = 10;
loop {
println!("remaining = {}", remaining);
if remaining == 9 {
break; // 退出内层循环 remaining
}
if count == 2 {
break 'counting_up; // 退出外层循环 count,标签counting_up
}
remaining -= 1;
}
count += 1;
}
println!("End count = {}", count);
// loop 退出并返回值
let mut counter = 0;
let result = loop {
counter += 1;
if counter == 10 {
break counter * 2;
}
};
println!("The result is {}", result);
// while
// 容易出现数组越界问题
let a = [10, 20, 30, 40, 50];
let mut index = 0;
while index < 5 {
println!("the value is: {}", a[index]);
index += 1;
}
// for
// 相对安全、简洁
let a = [10, 20, 30, 40, 50];
for element in a {
println!("the value is: {}", element);
}
// for 例子2,rev是反转区间函数
for number in (1..4).rev() {
println!("{}!", number);
}
println!("LIFTOFF!!!");
}
1、if
需要判断的是bool
值,与其他语言不同,不会将number
转化为bool
类型来判断。
2、if
可以与let
语句结合使用,只要if
表达式能够正确地返回值,并且if
与else
的返回值必须是同样的数据类型。
3、loop
需要break
来跳出循环,一般只会跳出内层循环,也可以指定跳出一个循环标签。
4、while
可以减少loop
的嵌套。
5、for
对集合进行遍历比while
跟安全简洁。
暂无补充
下一章即将进入“所有权”这个Rust独有的概念。