Rust快速学习开发(四)-常见编程概念

100 阅读7分钟

变量与可变性

不可变变量

rust中使用let声明的值,是不可变的。当变量不可变时,一旦值被绑定一个名称上,你就不能改变这个值。

fn main(){
    let x = 5;
    println!("The value of x is: {x}");
    x = 6;//error[E0384]: cannot assign twice to immutable variable `x` 不能对不可变变量 x 二次赋值
    println!("The value of x is: {x}");
}

变量

添加let声明后,let后面加 mut 来使变量变为可变的。

fn main(){
    let mut x=5;//添加 mut 来使变量变为可变的
    x=7;
    println!("the value of x is:{x}")
}

常量

  • 不允许对常量使用mut
  • 可以在任何作用域中声明
  • 常量只能被设置成常量表达式,而不可以是其他任务只能在运行时计算出的值
fn main(){
    //常量命名方式:全大写加下划线
    const IMMUTTABLE_VARIABLE:u32=20*30*99;
    println!("{IMMUTTABLE_VARIABLE}");
}

隐藏

  • 可以定一个与之前同名的新变量,rust称第一个变量被第二个隐藏
  • 隐藏与将变量标记为 mut 是有区别的。当不小心尝试对变量重新赋值时,如果没有使用 let 关键字,就会导致编译时错误。通过使用 let,我们可以用这个值进行一些计算,不过计算完之后变量仍然是不可变的。
  • .mut 与隐藏的另一个区别是,当再次使用 let 时,实际上创建了一个新变量,我们可以改变值的类型,并且复用这个名字
fn main(){
   //可以定一个与之前同名的新变量,rust称第一个变量被第二个隐藏
    let x=5;
    let x=x+2;
    {
        let x=x*2;
        println!("x1={x}")//14
    }
    println!("x2={x}")//7
}

函数

函数命名

rust中所有字母都是小写并使用下划线分隔单词

fn main(){//main 函数,程序入口
  println!("Hello, world!");
    anther_function();
}
//函数命名,所有字母都是小写并使用下划线分隔单词
fn anther_function(){
    println!("hello fn!!");
}

函数参数

  • 在函数签名中,必须 声明每个参数的类型
  • 如果定义多个参数,使用逗号分隔 rust中所有字母都是小写并使用下划线分隔单词
fn main(){//main 函数,程序入口
  println!("Hello, world!");
    anther_function(1,'h');
}

fn anther_function(x:i32,y:char){//1.在函数签名中,必须 声明每个参数的类型  2.如果定义多个参数,使用逗号分隔
    println!("anther function! of x is:{},of y is {}",x,y);
}

语句和表达式

语句(Statements)是执行一些操作但不返回值的指令。 表达式(Expressions)计算并产生一个值。

语句

实际上,我们已经使用过语句和表达式。使用 let 关键字创建变量并绑定一个值是一个语句。let y = 6; 是一个语句。 如下代码,语句并不没返回值,所以值没有绑定到x身上,c和c++中可以这样写 x = y = 6 rust中这样写会报错

fn main(){//main 函数,程序入口
  languge();
}

fn languge(){
   //语句 语句并不返回值,所以值没有绑定到x身上
  //let x=(let y=6);
  }
表达式
  • 表达式会计算出一个值,并且你将编写的大部分 Rust 代码是由表达式组成的。
  • 表达式的结尾没有分号。如果在表达式的结尾加上分号,它就变成了语句,而语句不会返回值。
fn main(){//main 函数,程序入口
 languge();
}
fn languge(){
 //表达式 表达式会计算出一个值,并且你将编写的大部分 Rust 代码是由表达式组成的。
 let x={
     let x=10;
     x+1//表达式的结尾没有分号。如果在表达式的结尾加上分号,它就变成了语句,而语句不会返回值
 };
 println!("x={x}");
}

具有返回值的函数

表达式返回值

函数可以向调用它的代码返回值。我们并不对返回值命名,但要在箭头(->)后声明它的类型。在 Rust 中,函数的返回值等同于函数体最后一个表达式的值。

fn main(){//main 函数,程序入口
  let a=five();
  let b=one(1);
  println!("a of five is: {},b of five is: {}",a,b);
}
fn five() -> i32 {
   5//表达式的结尾没有分号。
}
fn one(x:i32)->i32{
   x+1
}
使用return返回值

使用 return 关键字和指定值,可从函数中提前返回;但大部分函数隐式的返回最后的表达式。

fn main(){//main 函数,程序入口
  let c=return_one(1);
  println!("c of five is: {}",c);
}
fn return_one(x:i32)-> i32{
   return x+100;
}

注释

fn main() {
    println!("Hello, world!");
    // 单行注释
}

控制流

if表达式

  • 代码中的条件 必须 是 bool 值。如果条件不是 bool 值,如果不是将错误
  • 不像 Ruby 或 JavaScript 这样的语言,Rust 并不会尝试自动地将非布尔值转换为布尔值
  • 如果不提供 else 表达式并且条件为 false 时,程序会直接忽略 if 代码块并继续执行下面的代码。
fn main() {
   control_if();
}
//if表达式
fn control_if(){
    let number=10;

    if number < 5{//1.代码中的条件 必须 是 bool 值。如果条件不是 bool 值,如果不是将错误  2.不像 Ruby 或 JavaScript 这样的语言,Rust 并不会尝试自动地将非布尔值转换为布尔值
        println!("too small!");
    }else {//如果不提供 else 表达式并且条件为 false 时,程序会直接忽略 if 代码块并继续执行下面的代码。
        println!("too greater!");
    }

    if number!=0{//判断0
        println!("not null!");
    }
}

else if 多重处理

可以将 else if 表达式与 if 和 else 组合来实现多重条件

//else if 多重处理
fn control_else_if(){
    let number = 6;
    //可以将 else if 表达式与 if 和 else 组合来实现多重条件
    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");
    }
}

在let中使用if

因为 if 是一个表达式(表达式返回值),我们可以在 let 语句的右侧使用它 if和else分支返回的类型必须是相同的否则会报错(类型不匹配)

fn main() {
   control_let_if();
}

//在let中使用if
fn control_let_if(){
    let condition = true;
    //因为 if 是一个表达式,我们可以在 let 语句的右侧使用它  if和else分支返回的类型必须是相同的否则会报错(类型不匹配)
    let number = if condition {5} else {6};//{} 内就是表达式,要有返回值,末尾不能带分号
    println!("number is:{number}");
}

使用循环重复执行

在rust中可以使用loop循环执行代码块,使用break 停止循环并返回值

fn main() {
   control_loop();
}

//使用循环重复执行
fn control_loop(){
    let mut counter=0;
    let result=loop {//loop循环
        counter+=1;
        if counter==10{
           break counter+10; //break 停止循环并返回值
        }
        //命令提示符中 ctrl-c可以终止
       // println!("run loop!!!");
    };
    println!("result value is:{result}");
}

循环标签:在多个循环之间消除歧义

可以为loop循环定义标签,循环标签命名方式: '+名称,多重调用时使用标签控制可取消循环

fn main() {
   control_loop_label();
}

//循环标签:在多个循环之间消除歧义
fn control_loop_label(){
    let mut count=10;

    'loop_outside:loop{//循环标签命名方式: '+名称
        let mut in_count=0;
         loop{
             in_count+=2;
             println!("in_count:{in_count}");
             if in_count==6{
                 break;//内层loop结束
             };
             if count==2{
                 break  'loop_outside;//外层loop结束循环
             }
         };
         count -=1;
         println!("count:{count}");
    };
    println!("here of count is:{count}");
   
}

while条件循环

fn main() {
   control_while();
}

//while条件循环
fn control_while(){
    let mut number=3;
    //条件为 true 就执行,否则退出循环。
    while number!=1{//number 不等于0就一直循环
          println!("number is {number}");
          number-=1;
    };

    println!("number is {number}");

    //遍历集合  (容易出错,使用for循环更好)
    let a=["a","b","c","d","e"];
    let mut index=0;
    while index<5{//代码对数组中的元素进行计数。它从索引 0 开始,并接着循环直到遇到数组的最后一个索引(这时,index < 5 不再为真)
        println!("{index}and a of is {}",a[index]);
        index+=1;
    }
}   

for循环

使用 for 遍历集合
fn main() {
   control_for();
}

// for循环
fn control_for(){
    //使用 for 遍历集合
     let a=["a","b","c","d","e"];
     for i in a{
         println!("index of a is:{i}");
     };
} 

使用 for 循环遍历集合中的元素

下面是一个倒计时的示例,从10倒数到1,使用 Range,它是标准库提供的类型,用来生成从一个数字开始到另一个数字之前结束的所有数字的序列。

fn main() {
   control_for();
}

// for循环
fn control_for(){
     //使用 for 循环遍历集合中的元素
     for number in(1..10).rev(){//这么做的方式是使用 Range,它是标准库提供的类型,用来生成从一个数字开始到另一个数字之前结束的所有数字的序列。
           println!("{number}!");
     };
     println!("LIFTOFF!!!");
}