1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
use std::io;
pub fn enter(){
let result_of_fib = fibonacci(10);
println!("res is :{result_of_fib}");
return;
ch_03_01();
ch_03_02();
ch_03_03();
ch_03_04();
ch_03_05();
}
//斐波那契数列
//1,1,2,3,5,8,13,21,34,55,89...
//从第三项开始,每一项都等于前两项之和
fn fibonacci(level:i32)->i32{
// println!("num is:{level}");
// if level < 3{
// 1
// }else {
// fibonacci(level - 1) + fibonacci(level - 2)
// }
// if level < 1{
// return 0;
// }
if level <= 2{
// 1
return 1;
}
fibonacci(level - 1) + fibonacci(level - 2)
}
fn ch_03_05(){
//Rust中的if不需要加括号
let mut number:i32 = 5;
//但if后的花括号是必须要加的
if number < 3{
println!("number less than 3");
}else{
println!("number equal or greater than 3");
}
//也可以在let语句的右侧使用它
//类似于三元运算符 var x = contition ? 1 : 0;
let contition:bool = true;
let x = if contition {1} else {0};
//Rust的循环分为三种
//loop表示一个死循环直到你主动跳出循环,比如break
//它可以重复做一些操作和检查,比如检查线程是否完成了任务
let mut counter:i32 = 0;
let count_lmt:i32 = 100;
let mut result:i32 = 0;
//下面两段代码是等价的
// let result = loop{
// if counter >= count_lmt{
// //在Rust中,break和返回值都可以中断循环
// //使用return可以将loop的结果返回给result
// return counter;
// }
// counter += 1;
// };
loop{
if counter >= count_lmt{
result = counter;
break;
}
counter += 1;
}
//使用break可以中断指定标签的循环
// counter = 0;
//这是一个标签为"counting_up"的循环
//这段代码
'counting_up:loop
{
let mut remaining = 10;
loop
{
if remaining == 9{
break;
}
if counter == 2{
//中断标签为"counting_up"的循环,也就是最外层循环
break 'counting_up;
}
remaining -= 1;
}
counter += 1;
}
//还有一种循环是while
//和大多数语言一样,true继续执行,否则退出,通过break,continue,if等关键字控制流程
number = 10;
while number >=0
{
println!("number is:{number}");
number-=1;
}
//这是一个遍历数组的例子
let arr:[i32;5] = [10,20,30,40,50];
let mut index = 0;
let len = arr.len();
while index < len
{
println!("arr[index]");
index+=1;
}
//另外一个例子是for循环
//这有点类似于foreach循环
for element in arr{
println!("the current value of arr is {element}");
}
//也可以使用范围表达式来指定要遍历的集合范围
for num in (1..4).rev(){
println!("num is {num}");
}
}
fn ch_03_04(){
//注释,没啥好说的
}
fn ch_03_03(){
//Rust中所有的方法和变量遵循snake_case规则,即全部小写,以下划线分隔
//fn关键字声明新方法
let result = add_two_number(1,1);
println!("reuslt of function add(1,1) is {result}");
}
//带有一个i32类型参数的方法
fn another_function(x:i32){
println!("another_function,x->{x}");
}
//***Rust比较特殊的一点是,方法的返回值等同于方法体最后一个表达式的值
//带有一个u32参数,返回值类型为i32的方法
fn yet_another_function(val:i32)->i32{
//下面两种方式都可以作为返回值
//val;//将参数val作为返回值
5//整型5作为返回值
}
//使用return关键字作为返回值的方法
fn yet_another_function_return_with_bool(val:i32)->bool{
return false;
}
fn add_two_number(x:i32, y:i32)->i32{
return x + y;
}
fn ch_03_02(){
//Rust的数据类型分为两种子集:标量和复合
//Rust和C++一样,是静态类型语言,在编译时必须知道变量的类型
//通常情况下,根据值和使用方式,编译器可以推断出想要使用的类型,但在某些情况下必须注明,比如多种类型均有可能时(使用parse方法将String转换为数字时)
let number :u32 = "42".parse().expect("cast faild");
//标量类型代表一个单独的值,整型、浮点、布尔、字符
let f : bool = false;//一个bool类型
//***注意,Rust的Char类型大小为四字节,这可以让他比ASCII表示更多的内容,包括汉字、日文、韩文、甚至是Emoji等
//复合类型:元组和数组
//元组长度固定,一旦声明不可改变
let tup : (i32,f32,String) = (400, 10.0 , String::from("tuple"));//声明一个元组
//为了获取元组中的值,可以使用模式匹配来解构,像这样
// let (x,y,z) = tup;
// println!("x = {x},y = {y},z = {z}");
//也可以直接使用.来访问元组的成员
let test : i32 = tup.0;
let test : f32 = tup.1;
let test : &String = &tup.2;
println!("tup.0 = {},tup.1 = {}, tup.2 = {}", tup.0, tup.1, tup.2);
//Rust中,数组长度是固定的
let arr = [1,2,3,4,5];
let another_arr:[i32;5]=[1,2,3,4,5];//主动声明了类型和大小的数组
//访问数组元素
let first = arr[0];
let second = arr[1];
//不同于C#,Rust中数组存储在Stack上
}
fn ch_03_01(){
//声明常量使用const关键字,而非不带mut的let,并且必须注明值类型
//const可以在任何地方被声明,包括全局作用域
//Rust对常量的命名建议规范是全大写,下划线分隔
const MY_CONST:i32 = 10;
//Rust允许“隐藏”变量,此时任何使用该变量的地方都会视为使用隐藏后的变量,直到他的作用域结束
//隐藏和mut是有区别的,比如没有使用let关键字时会导致编译错误
//另外,当再次使用let时,实际上是创建了一个新变量
let x = 5;
let x = x + 1;
{
let x = x * 2;
}
//这里会导致编译报错,不能改变变量类型(mut)
// let mut spaces = " ";
// spaces = spaces.len();
}