• Rust通用编程概念(3)


    1.变量和可变性

    fn main() {
        let x = 10;
        println!("The value of x is:{}", x);
        x = 12;
        println!("The value of x is:{}", x)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    1.执行cargo run

    • 下图就是执行之后的报错信息
      在这里插入图片描述

    2.变量

    • rust定义的普通变量不能修改
    let [变量名] = [变量值]
    
    • 1

    3.变量的可变性

    • rust虽然普通定义的变量不可修改,可以添加关键字mut,让变量具有可变性
    let mut [变量名] = [变量值]
    
    • 1
    fn main(){
    	let mut x = 10;
    	println!("The value of x is:{}",x);
    	x = 12;
    	println!("The value of x is:{}",x);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    cargo run
    
    • 1
    The value of x is: 5
    The value of x is: 6
    
    • 1
    • 2

    4.常量

    • 常量是绑定一个常量名且不允许更改的值
    • 常量不允许使用mut
    • 常量使用const不是let关键词来声明,并且值的类型必须注明
    • 常量可以在任意作用域内声明
    const THREE_HOURS_IN_SECONDS: u32 = 60 * 60 * 3;
    
    • 1

    5.遮蔽

    fn main(){
    	let x = 8;
    	let x = x + 1;
    	{
    		let x = x * 2;
    		println!("The value of x in the inner scope is:{}",x);// 18
    		
    	}
    	println!("The value of x is: {}",x);// 9
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 首先将数值8绑定到x
    • 通过重复使用let x = 来遮蔽之前的x,并取原来的值+1
    • 作用域内,第三个let语句同样遮蔽前面的x,并且取之前值 * 2
    • 作用域结束,内部遮蔽结束并且x恢复为9
    5.1遮蔽与mut区别
    1.遮蔽
    • 通过let关键字,再一次有效的创建一个新的变量
    let spaces = "  ";// 字符串
    let spaces = spaces.len();// 数字类型
    
    • 1
    • 2
    2.mut
    • mut关键词主要是对变量的修改
    let spaces = "  ";// 字符串
    // spaces = spaces.len();// error,数字类型,赋值类型发生变化
    
    • 1
    • 2

    2.数据类型

    • Rust的每个值都有确切的数据类型,以下将主要展开两种数据类型:标量类型复合类型
    • Rust是一种静态类型的语言
    // cosider giving `guess` a type
    // let guess = "90".parse().expect("Not a number!");
    let guess: u32 = "90".parse().expect("Not a number!");
    
    • 1
    • 2
    • 3

    1.标量类型

    1.1整数类型
    长度有符号类型无符号类型
    8位i8u8
    16位i16u16
    32位i32u32
    64位i64u64
    128位i128u128
    archisizeusize
    • 有符号类型的数字范围是-2^(n-1) ~ 2^(n-1)-1
    • 无符号类型的数字范围是0~2^(n)-1
    • isize和usize类型取决于程序运行的计算机体系结构,64位架构系统则位64位,32位结构系统则为32位
    • isize和usize的主要场景是用作某些集合的索引
    1.2浮点数类型
    • 浮点数是带有小数点的数字,Rust中的浮点类型也有两种基本类型
    • Rust的浮点型是f32和f64,默认浮点类型是f64
    fn main(){
    let x = 2.3; // f64
    let y: f32 = 3.2; //f32
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    1.3数字运算
    • rust的所有数字类型都支持数学运算:加、减、乘、除和取模运算
    • 整数除法会向下取整
     //addition
        let sum = 5 + 10;
        println!("{}", sum);// 15
        //subtraction
        let difference = 96.6 - 94.7;
        println!("{}", difference);// 1.8999...
    
        //multiplication
        let product = 4 * 20;
        println!("{}", product);// 80
    
        //division
        let quotient = 63.3 / 23.3;
        let floored = 2 / 3;
        println!("{}", quotient);// 2.71673...
        println!("{}", floored);// 0
    
        //remainder
        let remainder = 43 % 5;
        println!("{}", remainder);// 3
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    1.4布尔类型
    • Rust中的布尔类型也有两个可能的值:true和false
    • 布尔值的大小为1个字节
    • Rust中的布尔值使用bool声明
    fn main(){
    
    	let t = true;
    	let f: bool = false
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    1.5字符类型
    • Rust的char(字符)类型是该语言基本的字母类型
    • Rust的字符类型大小为4个字节,表示一个Unicode标量值
    fn main(){
    	let c = 'c';
    	let b = 'b';
    	let heart_eyed_cat = '🐱';
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    2.复合类型

    • 复合类型可以将多个值组成一个类型,Rust有两种基本的复合类型:元组 和 数组
    2.1元组类型
    • 元组是将多种类型的多个值组合到一个复合类型中的基本方式
    • 元组的长度是固定的,声明后,它就无法增产或缩小
    fn main(){
    	let tup: (i32,f64,u8) = (500,23.3,5);
    }
    
    • 1
    • 2
    • 3
    • 变量tup绑定到整个元组,因为元素被认作是单个复合元素
    • 可以使用模式匹配来解构元组的一个值
    fn main(){
    	let tup = (500,6.2,3);
    	let (x,y,z) = tup;
    	println!("The value of y is:{}",y);// 6.4
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 通过模式匹配进行结构外,还可以通过 . 连上访问值得索引来直接访问元组元素
    • 元组中的第一个索引从0开始
    fn main(){
    	let x: (i32,f64,u8) = (500,6.3,23);
    	let five_hundred = x.0;
    	let six_point_three = x.1;
    	let twenty_three = x.2;
    	println!("{}",twenty_three);
    	
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    2.2数组类型
    • 将多个值组合在一起的另一种方式就是使用数组;与元组不同,数组的每个元素必须具有相同的类型;与其他语言不同数组不同的是,Rust中的数组具有固定长度.
    • 应用场景
      • 确保始终具有固定数量的元素,数组特别有用
      • Vector,在Rust里面,意为"动态数组,可变数组"
      • Vector类型类似于标准库中提供的集合类型
    let arr = [12,13,89,56,14];
    
    • 1
    • 另一种数组初始化方式
    // 变量名为arr的数组包含5个元素,这些元素的初始值都是3
    let arr = [3;5]
    
    • 1
    • 2
    1.访问数组
    • 数组是可以在栈上分配已知固定大小的单个内存块
    • 可以使用索引访问数组的元素
        let arr = [12, 13, 89, 56, 14];
        let first = arr[0];
        let second = arr[1];
        println!("{}", first); // 12
        println!("{}", second); // 13
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    2.无效的数组元素访问
    • 访问超出数组末尾的数组元素
    use std::io;
    fn main() {
        let arr = [12, 16, 45, 13, 19];
        println!("please enter an array index.");
    
        let mut index = String::new();
        io::stdin()
            .read_line(&mut index)
            .expect("Failed to read line");
    
        let index: usize = index
            .trim()
            .parse()
            .expect("Index entered was not a number");
        let element = arr[index];
        println!(
            "The value of the element at index {} is: {}",
            index, element
        );
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 该案例在索引操作使用无效值时导致运行时错误,程序退出并提示错误信息,未执行后面的println!语句
    • rust将检查你指定的索引是否小于或等于数组长度;索引大于或等于数组长度,rust会出现panic

    3.函数

    • main函数,它是很多程序的入口点
    • Rust代码中的函数和变量名使用下划线命名法规范风格
    • 在下划线命名法中,所有字母都是小写并使用下划线分隔单词
    fn main(){
    	println!("main funcation");
    	another_funcation();
    }
    fn another_function(){
    	println!("another function")
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    3.1定义函数

    • Rust中函数定义以 fn 开头,后跟着函数名和一对括号;大括号告诉编译器函数体在哪开始和结束

    3.2参数

    • 函数可以被定义拥有参数,参数是特殊变量,是函数签名的一分部
    • 当函数拥有参数(形参)时,这些参数提供具体的值(实参)
    • 日常交流中,人们倾向于不区分使用parameterargument来表示函数定义中的变量或调用函数时传入的具体值
    fn main(){
    	number_function(10);
    }
    fn number_function(x: i32){
    	println!("The value of x is:{}",x);//10
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    1.参数使用的注意事项
    • 函数签名中,必须声明每个参数的类型
    • 要求在函数定义中提供类型,意味着编译器几乎从不需要你在代码其他位置注明类型来指出你的意图
    • 一个函数有多个参数时,需要用 逗号隔开
    fn main(){
    	print_labeled_measurement(5,'h');
    }
    
    fn print_labeled_measurement(value: u32,unit_label: char){
    	println!("The measurement is:{}{}",value,unit_label);// 5h
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    3.3语句和表达式

    • 函数体由一系列语句组成,也可以选择表达式结尾
    • 语句是执行一些操作但不返回值的指令
    • 表达式计算并产生一个值
     //语句和表达式
        let y = 6;
        println!("{}", y);
        // 语句不会返回值
        // let x1 = (let y = 6);
        let y1 = {
            let x1 = 5;
            //行的末尾没有分号,表达式末尾加分号,那么它就转换为语句,而语句不会返回值
            x1 + 1
        };
        println!("The value of y1 is:{}", y1); // 6
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    3.4带有返回值的函数

    • 函数可以向调用它的代码返回值,但要在箭头(->)后声明它的类型
    • 在Rust中,函数的返回值等同于函数体最后一个表达式的值
    • 使用return关键字和指定值,可以从函数中提前返回;大部分函数隐式返回最后一个表达式
    fn five() -> u32{
    	5
    }
    fn main(){
    	let x = five();
    	println!("The value of x is: {},x);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 谨慎使用分号
    
    fn five_plus(x: u32) -> u32{
    	//如果在X+1后面加分号,表示语句,没有返回值,将报错
        // x + 1;
    	x + 1
    }
    fn main(){
    	let y = five_pluse(5);
    	println!("{}",y); //6
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    4注释

    4.1单行注释

    • Rust中,惯用的注释形式以两个斜杠开头,直到该行尾结束
    • 对于超出单行的注释,需要在每行的行首加上 //
    fn main(){
    	//I'm feeling lucky today
    	let lucky_number = 7;// I’m feeling lucky today
    }
    
    • 1
    • 2
    • 3
    • 4

    4.2多行注释

    • 使用斜杠星号开始和星号斜杠结束,可以跨越多行的注释
    /*
    这是一个做计算的方法
    	注意传值要求
    */
    fn plus_number(x: u32,y: i32) -> u32{
    	x + y
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    4.3文档注释

    • Rust允许你使用特殊的文档注释来为函数、结构体、枚举等代码元素添加文档注释
    • 文档注释以 /// 开始,通常紧跟在你要注释的代码元素之前
    /// 这是一个文档注释
    fn my_function(){
    
    }
    
    • 1
    • 2
    • 3
    • 4

    5.控制流

    • 根据条件是否为真来决定是否执行某些代码或根据条件是否为真来重复运行一段代码
    • Rust代码中最常见的用来控制执行流的结构是if表达式循环

    5.1if表达式

    • if 表达式允许根据条件执行不同的代码分支
    fn main(){
    	let number = 3;
    	if number < 5 {
    		println!("condition was true");
    	}else{
    		println!("condition was false");
    	}	
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 需要注意的事代码中的条件必须是bool值

    5.2使用else if处理多重条件

    • 可将if 和 else组成的 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");
    	}
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 注意事项
      • 使用过多的else if 表达式回事代码显得杂乱无章,如果超过一个else if 表达式,最好重构代码
      • 使用rust强大的分支结构,match

    5.3在let语句中使用if

    • if是一个表达式,可以在let语句的右侧使用它来将结果赋值给一个变量
    fn mian(){
    	let condition = true;
    	let number = if condition { 5 } else {6};
    	println!("The value of number is:{}",number);// 5
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    5.4使用循环重复执行

    • Rust有三种循环:loop、while和for
    1.使用loop重复执行代码
    • loop关键字告诉rust一遍又一遍执行一段代码知道你明确要求停止
    fn main(){
    	//这是一个死循环,通过ctrl+c终止循环
    	loop{
    		println!("again!");
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 存在嵌套循环,关键词break或continue可以和标签一起使用,有利于业务的实现
    fn main(){
    	let mut count = 0;
    	'counting_up': loop{
    		println!("count = {}",count);
    		let mut remaining = 10;
    	
    		loop {
    			println!("reamining = {}",remaining); 
    			if remaining == 9 {
    				break;
    			}
    			if count == 2 {
    				break 'counting_up';
    			} 
    			remaining -= 1;
    		}
    		count += 1;
    	}
    
    	println!("End count = {}",count);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    1.1从循环返回
    • loop的一个用例是重试可能会失败的操作
    • 有时可能会需要将操作的结果从循环中传递给其他的代码
    • 可以用停止循环的 break 表达式添加你想要的返回值
    fn main(){
    	let mut counter = 0;
    	let result = loop {
    		counter += 1;
    		if counter == 10 {
    			break counter * 2;
    		}
    	};
    	println!("The value is {}",result); // 20
    	
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    2.while条件循环
    fn main(){
    	let mut number = 3;
    	while number != 0{
    		println!("{}",number);
    		number -= 1;
    	}
    	println!("LIFTOFF!!!");
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    3.使用for遍历集合
    • while也可以实现遍历集合,但是容易出现下标越界问题,所以一般建议不使用
    • 更加推荐for去实现业务逻辑
    fn main() {
    	let arr = [10,20,30,40,50];
    	for element in arr {
    		println!("the value is: {}",element);
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
  • 相关阅读:
    C++之函数模板、类模板、模板的特化
    kubernetes从1.23.8升级到1.24.6
    开发工具篇第七讲:阿里云日志查询与分析
    计算机毕业设计Python+djang的药物管理系统
    c语言数据结构 排序(二)
    DataX: Ⅱ
    99%的时间里使用的14个git命令
    【0基础学算法】快速排序(超详细讲解+私人笔记+源码)
    MySQL教程
    js常用正则
  • 原文地址:https://blog.csdn.net/qq_39656068/article/details/132731828