一、变量与可变性
1、变量
在Rust语言中,变量默认是不可变的(immutable)。当变量不可变时,一旦值被绑定到一个名称上,你就不能改变这个值。
fn main() {
let mut x = 5;
println!{"The value of x is: {x}"};
x = 6;
println!{"The value of x is: {x}"};
}
Rust通过mut
将变量是否可变的决定权交给你,在变量前添加mut
即可让变量可变。
2、常量
常量(constants)是绑定到一个名称的不允许改变的值。
常量与变量的区别:
- 不允许对常量使用
mut
,常量不光默认不能变,它总是不能改变; - 声明常量使用
const
关键字而不是let
,并且必须注明值得类型;常量可以在任何作用域中声明,在声明它的作用域之中,常量在整个程序生命周期中都有效; - 常量只能被设置为常量表达式,而不可以是其他任何只能在运行时计算出得值;
声明常量的例子:
const THREE_HOURS_IN_SECONDS: u32 = 60 * 60 * 3;
Rust对常量的命名约定是在单词使用全大写并在单词之间添加下划线_
3、隐藏
在Rust中我们定义一个与之前变量同名的新变量,这称之为”第一个变量被第二个变量隐藏(Shadowing)“。第二个变量”隐藏“了第一个变量,此时任何使用该变量名的行为都会被视为在使用第二个变量,直到第二个变量自己也被隐藏或第二个变量的作用域结束。
fn main() {
let x = 5;
let x = x + 1;
{
let x = x * 2;
println!("The value of x in the inner scope is: {x} ");
}
println!("The value of x is: {x}");
}
输出如下:
隐藏与变量标记为mut
是有区别的:
- 当不小心尝试对变量重新赋值时,如果没有使用
let
关键字,就会导致编译错误,并且隐藏不改变值得不可变状态; - 当再次使用
let
时,实际上创建了一个新变量,我们可以改变值的类型,并且复用这个名字。
二、数据类型
在Rust中,每一个值都属于某一种数据类型(data type)。Rust时静态类型语言,在编译时必须直到所有变量的类型。
1、标量类型
标量(scalar)类型代表一个单独的值。
1.整形
整形是一个没有小数部分的数字。该类型表明,它关联的值应该是一个占据32位bit的无符号整数(有符号整数类型以i
开头,无符号整数类型u
开头)。
有符号:代表这个数有可能是负数;
无符号:代表这个数永远为正数;
另外isize
和usize
类型依赖运行程序的计算机架构:64位架构上它们是64位,32位架构上它们是3位。
可以使用如下表格中的任何一种形式编写数字面值。
例如:1_000
它的值与你指定的1000
相同。
2.浮点型
Rust有两个原生的浮点数类型。它们都是带小数点的数组。它们是f32
和f64
,分别占32位和64位。默认类型是f64
。所有的浮点型都是有符号的。
3.数值运算
Rust中的所有数字类型都支持基本数学运算:加法、减法、除法和取余。整数除法会向下舍入到最接近的整数。
fn main() {
let rets: u32 = 43 / 5;
println!("The {rets}");
}
4.布尔型
Rust中的布尔类型有可能的值:True
和False
。Rust中的布尔类型使用bool
表示。使用布尔值的主要场景是条件表达式。
5.字符类型
Rust的char
类型是语言中最原生的字母类型。注意,我们用单引号声明char
字面量,而与之相反的是,使用双引号声明字符串字面量。Rust的char
类型的大小位4个字节,并代表了一个Unicode标量值。
2、复合类型
复合类型可以将多个值组合成一个类型。Rust有两个原生的复合类型:元组(tuple)和数组(array)。
1.元组类型
元组是一个将多个其他类型的值组合进一个复合类型的主要方式。元组长度固定:一旦声明,其长度不会增长和缩小。
fn main() {
let tup: (i32, f64, u8) = (500, 6.4, 1);
}
tup
变量绑定到整个元组上,因为元组是一个单独的符合元素。为了从元组中获取单个值,可以使用模式匹配(pattern matching)来解构(destructure)元组值。
fn main() {
let tup = (500, 6.4, 1);
let (x, y, z) = tup;
println!("The value of y is: {x} {y} {z}");
}
不带任何值的元组有个特殊的名称,叫做单元(unit)。这种值以及对应的类型都协作()
,表示空值或空的返回类型。表达式不返回任何其他值,则会隐式返回单元值。
2.数组类型
另一个包含多个值的方式是数组(array),数组是在栈(stack)上为数据分配已知固定大小的单个内存块空间。与元组不同,数组中的每个元素的类型必须相同。Rust中的数组长度是固定的。
fn main() {
let a = [1, 2, 3, 4, 5];
}
但是数组不如vector类型灵活,vector类型是标准库提供的一个允许增长和缩小长度的类型数组的集合类型。
三、函数/参数
1、函数
main
函数是很多程序的入口点。fn
关键字,它用来声明函数。
fn main() {
println!("Hello, world!");
another_function();
}
fn another_function() {
println!("Another function.");
}
注意,在源代码中another_function
定义在main
函数之后;也可以定义在之前。Rust不关心函数定义所在的位置,只要函数被调用时出现在调用之处可见的作用域内就行。
2、参数
参数是特殊变量,是函数签名的一部分。形参(parameter)和(argument)来表示函数定义中的变量或调用函数时传入的具体值。
fn main() {
another_function(5);
}
fn another_function(x: i32) {
println!("The value of x is: {x}");
}
another_function
的声明中有一个命名x
的参数。x
的类型被指定为i32
,这个x
则为形参;当我们将5
传入another_function
时,println!
宏会八5
放在格式字符串中包含x
的那对花括号的位置,此时5
为实参。
在函数签名中,必须声明每个参数的类型。
当定义多个参数时,使用逗号分隔。
fn main() {
print_labeled_measurement(5, 'h');
}
fn print_labeled_measurement(value: i32, unit_label: char) {
println!("The measurement is: {value}{unit_label}");
}
3、语句和表达
函数体由一系列语句和一个可选的结尾表达式构成。
语句(Statements)时执行一些操作但不返回值的执行。表达式计算并产生一个值。
语句以分号结尾;表达式不以分号结尾;
4、具有返回值的函数
函数可以向调用它的代码返回值。但要在箭头(->
)后声明它的类型。
在Rust中,函数的返回值等同于函数体最后一个表达式的值。使用return
关键字和指定值,可以从函数中提前返回;但大部分函数隐式的返回最后的表达式。
fn five() -> i32 {
5
}
fn main() {
let x = five();
println!("The value of x is: {x}");
}
四、注释
注释有助于理解代码。
// hello, world
五、控制流
Rust代码中最常见的用来控制执行流的结构是if
表达式和循环。
1、if表达式
if
表达式允许根据条件执行不通的代码分支。你提供一个条件冰雹是“如果条件满足,运行这段代码;如果条件不满足,不运行这段代码。”
fn main() {
let number = 3;
if number < 5 {
println!("condition was true");
} else {
println!("condition was false");
}
}
另外值得注意的是代码中的条件必须是bool
值。
2、使用else if处理多重条件
可以使用else if
表达式与if
和else
组合来实现多重条件。
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");
}
}
3、在let语句使用if
因为if
是一个表达式,我们可以在let
语句的右侧使用它。
fn main() {
let condition = true;
let number = if condition { 5 } else { 6 };
println!("The value of number is: {number}");
}
在Rust中,变量必须只有一个类型。如果在变量中出现两种类型,那么就会出现错误。
fn main() {
let condition = true;
let number = if condition { 5 } else { "six" };
println!("The value of number is: {number}");
}
4、使用循环重复执行
Rust使用loop
重复执行代码。一个循环执行循环体中的代码直接到结尾并紧接着回到开头继续执行。
fn main() {
loop {
println!("again!");
}
}
当运行这个程序时,我们会看到连续的反复打印 again!
,直到我们手动停止程序。
1.从循环返回值
fn main() {
let mut counter = 0;
let result = loop {
counter += 1;
if counter == 10 {
break counter * 2;
}
};
println!("The result is {result}");
}
在循环之前,我们声明了一个名为 counter
的变量并初始化为 0
。接着声明了一个名为 result
来存放循环的返回值。在循环的每一次迭代中,我们将 counter
变量加 1
,接着检查计数是否等于 10
。当相等时,使用 break
关键字返回值 counter * 2
。循环之后,我们通过分号结束赋值给 result
的语句。最后打印出 result
的值,也就是 20。
2.循环标签
可以选择在玄幻上指定一个循环标签(loop label),然后将标签与break
或continue
一起使用,使这些关键字应用于已标记的循环而不是最内层的循环。
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
,它将从 0 数到 2。没有标签的内部循环从 10 向下数到 9。第一个没有指定标签的 break
将只退出内层循环。break 'counting_up;
语句将退出外层循环。
5、While条件循环
fn main() {
let mut number = 3;
while number != 0 {
println!("{number}!");
number -= 1;
}
println!("LIFTOFF!!!");
}
Rust内置了一个while
循环。
5、for循环
for
循环的安全性和简洁性使得它成为 Rust 中使用最多的循环结构。
使用for
循环来倒计时:
fn main() {
for number in (1..4).rev() {
println!("{number}!");
}
println!("LIFTOFF!!!");
}
标签:02,编程,number,let,Rust,println,main,基本概念,fn
From: https://www.cnblogs.com/ColoFly/p/16899894.html