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 的浮点数类型是 f32f64,分别占 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];
  1. 访问数组的方式
let num1=a[0];  //访问数组的方式
let num2=a[1];
  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方法来逆置数组,实现倒计时。

下期预告:所有权

posted @ 2022-09-13 18:40  hugeYlh  阅读(36)  评论(0编辑  收藏  举报  来源