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
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!