Rust的数据,函数及控制流内容总结
Rust的配置:Rust的安装与配置
Rust的猜数字游戏:猜数字
文章目录
变量与可变性
mut允许你指定哪一个变量是可变的,如果不指定mut,则此变量是只读的
fn main() {
let mut a=10;
println!("the value is mut:{}",a);
let b=99;
println!("the value is const:{}",b);
}
可以看到,Rust语言是很强大的,对指定为mut类型的变量如果在整个程序中没有对他进行修改,则会发出警告,建议您去掉mut修饰符
无法修改不加mut的变量,它会提示“不允许对一个不可变的值二次赋值”
常量
使用const 修饰符声明为常量,
不允许对常量使用 mut。常量不光默认不能变,它总是不能变。
声明常量使用 const 关键字而不是 let,并且 必须 注明值的类型。
const SIZE:i32=123456+222;
隐藏
声明第二个同名的变量会自动隐藏第一个同名的变量
- 同类型的转换:
let a=999;
let a=555;
println!("the really a is:{}",a);
- 不同类型的转换:
let str=" ";
let str=str.len();
println!("the length of str:{}",str);
将str的String类型转换为 i32 类型,变为长度。
数据类型
基本数据类型
Rust 是 静态类型(statically typed)语言,也就是说在编译时就必须知道所有变量的类型。
例如在编译时我们就应该指定此变量是哪一种类型:
let s=" 65 ";
let s: i32=s.trim().parse().expect("Not number!\n");
指定转换后的类型是: i32 类型。
- 整数类型
i和u分别表示有符号和无符号。i32类型即:有符号int类型,u32类型即:无符号int类型。 - 浮点类型
Rust 的浮点数类型是 f32 和 f64,分别占 32 位和 64 位。默认类型是 f64
let a:f32=1.255;
let b:f64=9.555555;
- 布尔类型
与其他语言一样,具有true和false两种类型
let a:bool=true;
- 字符类型
let c = 'z';
复合类型
元组
元组中的每一个位置都有一个类型,而且这些不同值的类型也不必是相同的。
let a:(u32,i32,i32,f64)=(55,11,22,66.22);
let (x,y,z,s)=a;
println!("a:{},{},{},{}",a.0,a.1,a.2,a.3);
println!("x:{},y:{},z:{},s:{}",x,y,z,s);
使用()其中每一个位置都有指定的类型,a表示元组名字。
使用了 let 和一个模式将 tup 分成了三个不同的变量,x、y 和 z。这叫做:解构
使用点来访问元组的元素。
打印出他们的值
数组
创建一个简单的数组
let a=[1,2,3,4,5,6];
数组的每一个元素都是固定的,同时数组的长度是固定的。
如果你想要动态修改数组的大小,建议使用vector,vector是替代数组的方式。
然而,如果你的数组一定不会改变长度,则使用数组会更简单。
指定数组的另一种方式:类型+元素个数
//方括号指定数组的类型和个数
let a:[u32;5]=[1,2,3,4,5];
- 访问数组的方式
let num1=a[0]; //访问数组的方式
let num2=a[1];
- 访问数组不能越界
//方括号指定数组的类型和个数
let a:[u32;5]=[1,2,3,4,5];
let num1=a[0]; //访问数组的方式
let num2=a[1];
let mut index=String::new(); //创建一个可变的变量
io::stdin().read_line(&mut index).expect("Error Input\n");
let index:usize=index.trim().parse().expect("Error Index\n");
println!("your 数组 is :{}",a[index]);
利用String转整数,如果超出索引则会报错
函数
如图,我们所写的每一个fn都是一个函数体
函数体不必在main的上面,例如C/C++,必须要在main之前提前声明,但是rust不用这样做,你可以随意改变函数的位置,因为rust是静态类型检查。
语句和表达式
- 语句: 只要后面带分号;,则是一条语句。
最简单的一条语句:
let a=1;
不能把let语句赋值给一个变量
let a=(let b=5); //Error
- 表达式:一般来说,不含;结尾的被称为表达式。
let c={let a=999; a+10 };
用大括号括起来的块作用域也是一个表达式。
这一个表达式说明了:在给c赋值的时候,里面有一个语句和一条表达式,最后执行a+10语句,同时大括号里的都是一条语句,1009赋值给变量c。
具有返回值的函数
下面这一条代码,你可能会感到奇怪:
fn main() {
//ps1();
//const_vaiables();
//ps3();
//ps4();
println!("这个函数的返回值:{}",return_num());
}
fn return_num()->u32
{
5
}
在函数的尾部使用 ->返回类型 指定返回值的类型
函数的返回值等同于函数体最后一个表达式的值。使用 return 关键字和指定值,可从函数中提前返回;但大部分函数隐式的返回最后的表达式,例如本例中的直接写一个数字:5 ,返回默认的表达式5(不带括号,否则就是一条语句了)
当然,你应该显示指定return返回。
fn return_num()->u32
{
return 5;
}
往函数传递参数:
fn return_num(x:u32)->u32
{
return x+10;
}
fn return_num(x:u32)->u32
{
x+10 //无分号
}
往函数传递x值。
注意:函数的返回值等于函数体最后一个表达式的值,使用return是提前返回;单独写一条语句则是隐式返回最后的表达式。
但是函数的表达式中加上分号则会出错,编译器会提示你把分号去掉。
错误:函数要求一个表达式,但是他却是一个语句。
控制流
if表达式
fn if_num()
{
let a=5;
if a<5{
println!("Little than 5.");
}else {
println!("Big or Equal than 5.");
}
}
注意:Rust不会像C++那样,默认转换为bool类型。
if a{
println!("Little than 5.");
}
会出错,可以显示指定 a != 0。
else if 多重循环
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");
}
}
使用过多的 else if 表达式会使代码显得杂乱无章,所以如果有多于一个 else if 表达式,最好重构代码。使用:match。
在let中使用if
大括号是一个表达式,temp是bool类型,如果为true,返回表达式5,否则,返回表达式6.
fn if_num2()
{
let temp=true;
let a={
if temp{
5
}else{
6
}
};
println!("a的值是:{}",a);
}
注意:if else如果当作let的返回值,则必须是同一类型的变量,否则编译器会无法识别。
loop循环
相当于while(1):
loop {
println!("5");
}
使用 ctrl+c 来终止循环。
从循环返回值
fn loop_num3()
{
let mut a=10;
let num=loop {
a-=1;
if a==1
{
break a;
}
};
println!("num is:{}",num);
}
在let赋值时使用loop循环来找到一个可以停止循环的终止条件:当a==1的时候,此时break附带一个返回值 a,做到了给变量num的赋值。
for遍历数组
最普通的遍历方式:
fn travel1()
{
let a:[u32;5]=[1,2,3,4,5];
let mut index=0;
//遍历
while (index<5)
{
println!("a[{}]={}",index,a[index]);
index+=1;
}
}
但是这种方式很容易造成越界,同时对数据的统一维护不高,我们使用Rust提供的便捷的方式:
fn travel1()
{
let a:[u32;5]=[1,2,3,4,5];
let mut index=0;
//遍历
for elem in a
{
println!("{}",elem);
}
}
有点像python遍历的方式。
下面是一个使用 for 循环来倒计时的例子,它还使用了一个我们还未讲到的方法,rev,用来反转 range:
fn travel1()
{
for elem in (1..5).rev()
{
println!("{}",elem);
}
println!("boom!!!\n");
}
注意:匿名区间(1…4)是左闭右开的,(1…=4)是左右闭的,两者不同,同时使用rev方法来逆置数组,实现倒计时。
下期预告:所有权
本文来自博客园,作者:hugeYlh,转载请注明原文链接:https://www.cnblogs.com/helloylh/p/17209718.html