第3章 通用的编程概念
变量、常量、隐藏机制
变量与隐藏的特点
- let 声明的变量为不可改变的变量
- let mut 声明的变量是可变变量
- 可以使用let 重新声明已经用let 声明的变量,原来的变量的值会被覆盖, 这个现象叫做隐藏。
- 隐藏机制(可以理解为重新定义)可以用let 重新声明与原let 声明的变量的类型不一致的变量。但是使用let mut 就必须声明与原let mut 声明的类型一致变量。
实例:
fn main() {
let x = 8;
let x = x + 6;
let mut y = 9;
let mut y = y + 2; // 编译会用告警,显示y的可变性没有用到。直接用let y = y + 2就行
println!("x = {} y = {}", x, y);
}
常量的特点
- 不能用let mul声明一个常量,常量用const 修饰,而且使用全大写、下划线分割声明
- 常量在整个程序运行的过程中都在自己声明的作用域有效。
- 常量总是需要标注类型。
- 常量的值永远不会改变。
实例:
const MAX_VLAUE: u32 = 10_000;
数据类型
两类内置的数据类型
- 标量类型:整数、浮点数、布尔值和字符。
- 复合类型:元祖和数组
标量类型
整数:
- rust 对于整数字面量都默认推导为 i32 类型,除非显示声明 如 62u32、88i16
- 关于整数溢出现象,对于debug模式下会引起panic,但对于release模式会发生回绕。
- 其他请参考P51
浮点数:
- rust 对于浮点字面量都默认推导为 f64 类型。同整数
布尔类型:
- 使用bool 类型修饰为布尔类型 其值为ture 和 false
字符类型:
- rust 中字符变量占4个字节。
复合类型
元组类型
- 元组拥有一个固定的长度,你无法在声明结束后增加或者减少其中的元素。
- 元组中的元素的类型可以不一致。
- 可以使用模式匹配解构元组,也可以通过索引并使用点号(.)访问元组的值。
fn main() {
let tup: (u32, f32, i32) = (30, 50.0, 90);
let (x, y, z) = tup; // 模式匹配解构元组
let a = tup.0; // 通过索引并使用点号(.)访问元组中的值
let b = tup.1;
let c = tup.2;
println!("{} {} {}", x, y, z);
println!("{} {} {}", a, b, c);
}
数组类型:
- 数组中的元素的类型必须一致。
- 元组拥有一个固定的长度,你无法在声明结束后增加或者减少其中的元素。
- 可以通过索引并+ []访问数组的值。
- 非法的数组访问在编译时会发生panic
数组的访问:
fn main() {
let a: [u32; 5] = [1, 2, 3, 4, 5];
let b = [10, 20, 30, 30, 40, 50];
let c = [3; 5]; // 等价与 let c = [3, 3, 3, 3, 3];
println!("{} {} {}", a[0], b[0], c[0]);
}
函数
命名与定义
- 使用蛇形命名法,即使只用小写的字母进行命令并以下划线分割单词
- 使用fn + name + () + -> + 类型进行函数声明。
- rust不关心在何处定义函数,只要这些定义对于使用区间可用即可。
参数与返回值
- 在函数签名(参数)中必须显示声明每个参数的类型,并使用逗号分割参数。
- 返回值可用return显示返回,也可以通过最后一行的表达式进行返回。
函数体中的表达式和语句
- 语句为执行操作但不返回值的指令,表达式则是会返回值的的指令。语句有分号。
- 表达式一般包括调用函数、调用宏、花括号等。
fn main() {
let a = 5;
let b = 10;
println!("{}", sum(a, b));
}
fn sum(a: i32, b: i32) -> i32 {
a + b // 注意这里没有分号,有分号就表示语句则会发生编译错误。
}
控制流
**条件语句 if **
if 5 > 0 {
5
} else {
0
}
循环 - loop、while、for
loop
fn main() {
let mut count = 0;
let s = loop { // 类似while(1)
count += 1;
if count == 10 {
break count * 2;
}
};
println!("{}", s);
let mut number = 2;
while number != 0{
println!("{}", number);
number -= 1;
}
let a = [1, 2, 3, 4, 5];
for number in a[0..4].iter().rev() { // 使用for 来遍历元组或数组更好,rev函数为翻转数组
println!("{}", number);
}
}
输出n阶斐波拉契数列
use std::io;
fn main() {
let mut my_string = String::new();
let mut array = [0; 100];
io::stdin().read_line(&mut my_string).expect("xxx");
let n: usize = my_string.trim().parse().expect("yyyy"); // trim()去掉空格, parse() 字符串转换成数字。
array[0] = 1;
array[1] = 1;
println!("{}", array[0]);
println!("{}", array[1]);
let mut i = 2;
loop {
array[i] = array[i-1] + array[i-2]; // 数组的下标为usize类型
println!("{}", array[i]);
i += 1;
if i > n {
break;
}
}
}