Rust常用语法
Rust变量及可变性
Rust变量
Rust变量默认的不可变性
let x = 5;
x = 6;
这样是无法将变量变值的,因为这个变量是默认具有不可变性。
let mut x = 5;
x = 6;
可以使用mut对不可变性进行修改。
Rust中常量的表达
fn main() {
const THREE_HOURS_IN_SECONDS: u32 = 60 * 60 * 3;
}
常量要注意的是只能具有常量表达式,而不能作为变量运行结果。
常量在RUST中只能使用大写字母+“_”的方式出现
将整个程序中使用的硬编码值命名为常量,有助于向将来的代码维护者传递该值的含义。如果将来需要更新硬编码的值,代码中只有一个地方需要更改,这也会有所帮助
Rust变量可变性
Rust中覆盖操作
使用let
命令可以对rust中的参数进行覆盖操作,
let x = 3;
let x = x+1;
{
let x=x*2;//x=8
println!("x={x}");//x=8
}
println!("x={x}");//x=4
let定义的变量同样具有作用域。
let spaces = " ";
let spaces = spaces.len();
let
同时可以对不同类型的变量使用同一个名称,而mut则不可以。
fn main() {
let mut spaces = " ";
spaces = spaces.len();
}
$ cargo run
Compiling variables v0.1.0 (file:///projects/variables)
error[E0308]: mismatched types
--> src/main.rs:3:14
|
2 | let mut spaces = " ";
| ----- expected due to this value
3 | spaces = spaces.len();
| ^^^^^^^^^^^^ expected `&str`, found `usize`
For more information about this error, try `rustc --explain E0308`.
error: could not compile `variables` due to previous error
Rust数据类型
Rust是一种静态类型语言,所有元素在编译之前都必须知道它的具体确切类型。
Rust标量类型
整型
整型变量默认是i32格式
整型变量分为有符号(signed)和无符号整形变量(unsigned),有符号变量存放形式为补码。
每个有符号类型规定的数字范围是 -(2n - 1) ~ 2n - 1 - 1,其中 n 是该定义形式的位长度。所以 i8 可存储数字范围是 -(27) ~ 27 - 1,即 -128 ~ 127。无符号类型可以存储的数字范围是 0 ~ 2n - 1,所以 u8 能够存储的数字为 0 ~ 28 - 1,即 0 ~ 255。
isize
和 usize
类型取决于程序运行的计算机体系结构,在表中表示为“arch”:若使用 64 位架构系统则为 64 位,若使用 32 位架构系统则为 32 位。
isize:指针大小的有符号整数类型
usize:指针大小的无符号整数类型
你可按表中所示的任意形式来编写整型的字面量。注意,可能属于多种数字类型的数字字面量允许使用类型后缀来指定类型,例如 57u8。数字字面量还可以使用 _ 作为可视分隔符以方便读数,如 1_000,此值和 1000 相同。
- Rust中的整数溢出后,会使用
panic
来表示程序错误退出。 - 而在rust使用 --release进行发布时,会优化代码,将其中的错误数值:如256–>0,257–>1,以此类推。
这一部分还没有了解清楚:
要显式处理溢出的可能性,可以使用标准库针对原始数字类型提供的以下一系列方法:
- 使用 wrapping_* 方法在所有模式下进行包裹,例如 wrapping_add
- 如果使用 checked_* 方法时发生溢出,则返回 None 值
- 使用 overflowing_* 方法返回该值和一个指示是否存在溢出的布尔值
- 使用 saturating_* 方法使值达到最小值或最大值
浮点型
浮点型有两种,一种是f32
(单精度浮点型),一种是f64
(双精度浮点型),默认为f64
,因为两种在cpu中运行速度相同。
fn main() {
let x = 2.0; // f64
let y: f32 = 3.0; // f32
}
数值运算
数值运算中需要注意的是:除法会向下取整
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;
}
布尔类型
rust中的布尔类型使用bool定义
fn main() {
let t = true;
let f: bool = false; // with explicit type annotation
}
字符类型
Rust 的字符类型大小为 4 个字节,表示的是一个 Unicode 标量值,这意味着它可以表示的远远不止是 ASCII。
fn main() {
let c = 'z';
let z = 'ℤ';
let heart_eyed_cat = '😻';
}
Rust复合类型
元组和数组
元组类型
元组类型长度固定,但是可以将多个不同类型变量储存。
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);//y=6.4
}
元组类型的访问
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;
}
数组类型
数组具有固定长度,而且数组中元素类型必须相同,但是vector
(动态数组)可以改变长度
数组中遇到字符串需要使用双引号,字符使用单引号
fn main() {
let a = [1, 2, 3, 4, 5];
}
fn main() {
let months = ["January", "February", "March", "April", "May", "June", "July",
"August", "September", "October", "November", "December"];
}
使用方括号编写数组的类型,其中包含每个元素的类型、分号,然后是数组中的元素数,如下所示:
fn main() {
let a: [i32; 5] = [1, 2, 3, 4, 5];
}
对于每个元素都相同的情况,还可以通过指定初始值、后跟分号和方括号中的数组长度来初始化数组,如下所示:
fn main() {
let a = [3; 5];
}
访问数组元素:
fn main() {
let a = [1, 2, 3, 4, 5];
let first = a[0];
let second = a[1];
}
数组元素访问:通过索引来访问。
use std::io;
let a = [1,2,3,4,5];
println!("Please input your index!");
let mut index = String::new();
io::stdin()
.read_line(&mut index)
.expect("Failed to input the index");
let index: usize = match index.trim().parse()
{
Ok(num) => num,
Err(_) => todo!(),
};
let element = a[index];
println!("the value of the element in the {index} is:{element}");
}
Rust函数
- Rust中的函数命名格式是:小写字母加下划线,这正好与其在const常数中相对应。
- 注意:Rust中函数定义时比较特殊,它对主函数和其他函数的位置没有明确表示,也就是说可以放在主函数之前,也可以放在其后。
- Rust中函数的参数必须标明数据类型
Rust语句
- 在rust中比较强调语句,rust中语句不返回值,只有表达式返回值,因此不能:
let x=(let x=6);
但是,同时也可以这样写:
fn main() {
let y={
let x=3;
x+1
};
println!("The value of y is:{}",y);//y=4
}
这其中x+1没有分号,因为它是一个表达式,表达式return结果给y.
Rust函数返回值
fn five() ->i32
{
5
}
fn main(){
let x =five();
println!("The value of x is:{x}");
}
five()
函数是一个没有参数的返回值是i32
类型的函数,因为5是一个表达式,有返回值,所以能够运行。
- 在函数中若想要使用返回值,必须对函数函数返回值类型进行定义。定义方法是 ->类型。
- 而函数的返回值是函数中最后一个表达式的值,同时你也可以使用
return
关键字提前返回。
fn main()
{
let x = plus_one(5);
println!("The value of x is:{x}");
}
fn plus_one(x: i32) -> i32{
x+1
}
此时,便不难理解函数中的结果。
如果给函数体内部不添加任何表达式,就会有下面的结果(直接把官方文档拿来粘贴一下)
注释
注释和C语言中注释相同,均为//
,/**/
。
fn main() {
// I’m feeling lucky today
let lucky_number = 7;
}
官方建议是将注释放被解释代码的上一行单独使用,养成一个良好的写代码习惯吧!
控制流
经典的if
语句
fn main() {
let number = 3;
if number < 5 {
println!("condition vas true")
}else{
println!("condition vas false");
}
}
if
语句是比较常见的语句了,在RUST中它和match
有点相似。
- 如果if语句中没有else判断,且判断为假,那么会直接执行下面的语句。
- 下面是官方文档:
- if语句中的判断必须为
bool
,即0和1.
elseif的使用:
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");
}
}
在其他的代码中常常会看到这样的语句,但是在Rust中有match
,之后详谈。
let语句中使用if
fn main()
{
let condition = true;
let number = if condition {5} else {6};
println!("The value of number is:{number}");
}
if语句中的返回值必须是相同类型,这段代码是可以正常执行的,但是,如果改成下面的代码:
fn main() {
let condition = true;
let number = if condition { 5 } else { "six" };
println!("The value of number is: {}", number);
}
会提示if and else have incompatible type.
循环语句
Rust中循环语句有三种类型,loop
,while
,for
loop
fn main()
{
loop
{
println!("again!");
}
}
- loop是会将其陷入一个死循环,但是可以使用
crtl+c
退出,或者break,continue
跳出循环
fn main()
{
loop
{
println!("again!");
}
}
- loop多层循环示例:
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 'counting_up;
}
remaining-=1;
}
count+=1;
}
println!("End count = {count}");
}
- 其中的
'counting_up:loop
和break 'counting_up;
相对应,这一部分有点类似于goto
语句,是为了跳出外层循还所设置的。
- 结果如图所示。
loop
的一个用例是重试可能会失败的操作,比如检查线程是否完成了任务。然而你可能会需要将操作的结果从循环中传递给其它的代码。为此,你可以在用于停止循环的break
表达式添加你想要返回的值;该值将从循环中返回,以便您可以使用它
fn main()
{
let mut counter = 0;
//看到这儿,loop将berak返回值设置为counter*2
let result = loop
{
counter+=1;
if counter == 10
{
break counter*2;
}
};
println!("The result is:{result}");
}
while条件循环语句
while条件语句是在条件表达式为真的情况下会运行,即先判断,再运行
fn main() {
let mut number = 3;
while number != 0 {
println!("{}!", number);
number -= 1;
}
println!("LIFTOFF!!!");
}
fn main()
{
let a=[10,20,30,40,50];
let mut index = 0;
while index < 5
{
println!("the value is:{}",a[index]);
index+=1;
}
}
此处println!("the value is:{a[index]}");
会报错,
使用for遍历循环
上述这段代码可以使用for循环来代替,
fn main()
{
let a = [10,20,30,40,50];
for element in a{
println!("the value is :{}",element);
}
}
*这段代码中需要说明的是for element in a
即为遍历a中的元素。
for element in a{
println!("the value is:{}",element);
}
- 接着是一段官方文档(~不想打了)
- 这里首先使用range函数生成1到4之前的数,即为1、2、3,然后再使用.rev()进行反转数字