Rust通用编程概念(3)

news2024/11/22 23:38:05

Rust通用编程概念

    • 1.变量和可变性
      • 1.执行`cargo run`
      • 2.变量
      • 3.变量的可变性
      • 4.常量
      • 5.遮蔽
        • 5.1遮蔽与mut区别
          • 1.遮蔽
          • 2.mut
    • 2.数据类型
      • 1.标量类型
        • 1.1整数类型
        • 1.2浮点数类型
        • 1.3数字运算
        • 1.4布尔类型
        • 1.5字符类型
      • 2.复合类型
        • 2.1元组类型
        • 2.2数组类型
          • 1.访问数组
          • 2.无效的数组元素访问
    • 3.函数
      • 3.1定义函数
      • 3.2参数
        • 1.参数使用的注意事项
      • 3.3语句和表达式
      • 3.4带有返回值的函数
    • 4注释
      • 4.1单行注释
      • 4.2多行注释
      • 4.3文档注释
    • 5.控制流
      • 5.1if表达式
      • 5.2使用else if处理多重条件
      • 5.3在let语句中使用if
      • 5.4使用循环重复执行
        • 1.使用loop重复执行代码
          • 1.1从循环返回
        • 2.while条件循环
        • 3.使用for遍历集合

1.变量和可变性

fn main() {
    let x = 10;
    println!("The value of x is:{}", x);
    x = 12;
    println!("The value of x is:{}", x)
}

1.执行cargo run

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

2.变量

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

3.变量的可变性

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

4.常量

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

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);// 12
		
	}
	println!("The value of x is: {}",x);// 6
}
  • 首先将数值5绑定到x
  • 通过重复使用let x = 来遮蔽之前的x,并取原来的值+1
  • 作用域内,第三个let语句同样遮蔽前面的x,并且取之前值 * 2
  • 作用域结束,内部遮蔽结束并且x恢复为6

5.1遮蔽与mut区别

1.遮蔽
  • 通过let关键字,再一次有效的创建一个新的变量
let spaces = "  ";// 字符串
let spaces = spaces.len();// 数字类型
2.mut
  • mut关键词主要是对变量的修改
let spaces = "  ";// 字符串
// spaces = spaces.len();// error,数字类型,赋值类型发生变化

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.标量类型

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.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.4布尔类型

  • Rust中的布尔类型也有两个可能的值:true和false
  • 布尔值的大小为1个字节
  • Rust中的布尔值使用bool声明
fn main(){

	let t = true;
	let f: bool = false
}

1.5字符类型

  • Rust的char(字符)类型是该语言基本的字母类型
  • Rust的字符类型大小为4个字节,表示一个Unicode标量值
fn main(){
	let c = 'c';
	let b = 'b';
	let heart_eyed_cat = '🐱';

}

2.复合类型

  • 复合类型可以将多个值组成一个类型,Rust有两种基本的复合类型:元组 和 数组

2.1元组类型

  • 元组是将多种类型的多个值组合到一个复合类型中的基本方式
  • 元组的长度是固定的,声明后,它就无法增产或缩小
fn main(){
	let tup: (i32,f64,u8) = (500,23.3,5);
}
  • 变量tup绑定到整个元组,因为元素被认作是单个复合元素
  • 可以使用模式匹配来解构元组的一个值
fn main(){
	let tup = (500,6.2,3);
	let (x,y,z) = tup;
	println!("The value of y is:{}",y);// 6.4

}
  • 通过模式匹配进行结构外,还可以通过 . 连上访问值得索引来直接访问元组元素
  • 元组中的第一个索引从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);
	
}

2.2数组类型

  • 将多个值组合在一起的另一种方式就是使用数组;与元组不同,数组的每个元素必须具有相同的类型;与其他语言不同数组不同的是,Rust中的数组具有固定长度.
  • 应用场景
    • 确保始终具有固定数量的元素,数组特别有用
    • Vector,在Rust里面,意为"动态数组,可变数组"
    • Vector类型类似于标准库中提供的集合类型
let arr = [12,13,89,56,14];
  • 另一种数组初始化方式
// 变量名为arr的数组包含5个元素,这些元素的初始值都是3
let arr = [3;5]
1.访问数组
  • 数组是可以在栈上分配已知固定大小的单个内存块
  • 可以使用索引访问数组的元素
    let arr = [12, 13, 89, 56, 14];
    let first = arr[0];
    let second = arr[1];
    println!("{}", first); // 12
    println!("{}", second); // 13
}
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
    );
}
  • 该案例在索引操作使用无效值时导致运行时错误,程序退出并提示错误信息,未执行后面的println!语句
  • rust将检查你指定的索引是否小于或等于数组长度;索引大于或等于数组长度,rust会出现panic

3.函数

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

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.参数使用的注意事项

  • 函数签名中,必须声明每个参数的类型
  • 要求在函数定义中提供类型,意味着编译器几乎从不需要你在代码其他位置注明类型来指出你的意图
  • 一个函数有多个参数时,需要用 逗号隔开
fn main(){
	print_labeled_measurement(5,'h');
}

fn print_labeled_measurement(value: u32,unit_label: char){
	println!("The measurement is:{}{}",value,unit_label);// 5h
}

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

3.4带有返回值的函数

  • 函数可以向调用它的代码返回值,但要在箭头(->)后声明它的类型
  • 在Rust中,函数的返回值等同于函数体最后一个表达式的值
  • 使用return关键字和指定值,可以从函数中提前返回;大部分函数隐式返回最后一个表达式
fn five() -> u32{
	5
}
fn main(){
	let x = five();
	println!("The value of x is: {},x);
}
  • 谨慎使用分号

fn five_plus(x: u32) -> u32{
	//如果在X+1后面加分号,表示语句,没有返回值,将报错
    // x + 1;
	x + 1
}
fn main(){
	let y = five_pluse(5);
	println!("{}",y); //6
}

4注释

4.1单行注释

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

4.2多行注释

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

4.3文档注释

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

}

5.控制流

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

5.1if表达式

  • if 表达式允许根据条件执行不同的代码分支
fn main(){
	let number = 3;
	if number < 5 {
		println!("condition was true");
	}else{
		println!("condition was false");
	}	
}
  • 需要注意的事代码中的条件必须是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");
	}

}
  • 注意事项
    • 使用过多的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
}

5.4使用循环重复执行

  • Rust有三种循环:loop、while和for

1.使用loop重复执行代码

  • loop关键字告诉rust一遍又一遍执行一段代码知道你明确要求停止
fn main(){
	//这是一个死循环,通过ctrl+c终止循环
	loop{
		println!("again!");
	}
}
  • 存在嵌套循环,关键词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.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
	
}

2.while条件循环

fn main(){
	let mut number = 3;
	while number != 0{
		println!("{}",number);
		number -= 1;
	}
	println!("LIFTOFF!!!");
}

3.使用for遍历集合

  • while也可以实现遍历集合,但是容易出现下标越界问题,所以一般建议不使用
  • 更加推荐for去实现业务逻辑
fn main() {
	let arr = [10,20,30,40,50];
	for element in arr {
		println!("the value is: {}",element);
	}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1004734.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

9月12日作业

作业代码 #include <iostream>using namespace std;class Shape { protected:double cir;double area; public://无参构造Shape() {cout<<"无参构造"<<endl;}//有参构造Shape(double c, double a):cir(c), area(a){cout<<"有参构造&quo…

Maven Helper mvn项目冲突如何解决

一般用这款插件来查看maven的依赖树。 一、安装&#xff1a; File-->setting--->Plugins--->在搜索框中填写Maven Helper然后搜索&#xff0c;单击Install按钮进行安装&#xff0c;装完重启IDE。 二、使用 当Maven Helper 插件安装成功后&#xff0c;打开项目中的p…

【算法基础】时间复杂度和空间复杂度

目录 1 算法的评价 2 算法复杂度 2.1 时间复杂度&#xff08;Time Complexity&#xff09; 2.1.1 如何计算时间复杂度&#xff1a; 2.1.2 常见的时间复杂度类别与示例 2.2 空间复杂度 2.2.1 如何计算空间复杂度 2.2.2 常见的空间复杂度与示例 3 时间复杂度和空间复杂度…

docker 部署 node.js(express) 服务

1、在 express 项目根目录下新增 Dockerfile 文件&#xff0c;内容如下&#xff1a; 创建服务容器的方法&#xff0c;可以根据自己的情况选择&#xff1a; 1、以下示例为宿主机没有安装 node 环境的写法&#xff1b; 2、先在本地构建包含 node 和 express 的基础镜像&#xff0…

【C++】day5学习成果:继承和六个特殊成员函数的代码应用、静态成员 继承 类的关系模型 类的继承步骤的思维导图。

1.代码题&#xff1a;实现一个图形类&#xff08;Shape&#xff09;&#xff0c;包含受保护成员属性&#xff1a;周长、面积&#xff0c; 公共成员函数&#xff1a;特殊成员函数书写 定义一个圆形类&#xff08;Circle&#xff09;&#xff0c;继承自图形类&#xff0c;包含私有…

STC15/8单片机特有的PWM寄存器和普通定时器实现PWM输出

STC15/8单片机特有的PWM寄存器和普通定时器实现PWM输出 🌿主要针对STC15W4型号特有的6通道15位专门的高精度PWM。 🌿STC8系列 ✨STC15W4K32S4系列单片机具有6通道15位专门的高精度PWM(带死区控制)和2通道CCP(利用它的高速脉冲输出功能可实现11~16位PWM);(STC15F/L2K60S2系…

JAVA8接口使用问题

JAVA8接口使用问题 文章目录 JAVA8接口使用问题1、默认方法冲突问题&#xff08;1&#xff09;亲爹优先原则&#xff08;2&#xff09;左右为难 2、常量冲突问题 1、默认方法冲突问题 &#xff08;1&#xff09;亲爹优先原则 当一个类&#xff0c;既继承一个父类&#xff0c;…

助力智能化公路养护,基于YOLOv5s集成SPD-BIFPN-SE开发构建公路开裂检测识别系统

在前文中我们尝试构建了在隧道、涵洞尝尽下的自动智能化养护巡查相关的模型&#xff0c;进行了实地测试评估&#xff0c;感兴趣的话可以自行移步阅读即可&#xff1a; 《基于轻量级YOLOv5s开发构建隧道基建裂痕、脱落等缺陷问题检测系统》 本文的想法是相近的&#xff0c;核心…

Linkerd2初探

Linkerd2初探 部署环境Linkerd简介安装Linkerd客户端在k8s上安装Linkerd控制平面&#xff08;服务端&#xff09;实验&#xff1a;数据平面代理注入demo应用安装viz插件&#xff08;可视化面板&#xff09;部署grafana 其他 部署环境 k8s环境: KIND 模拟kubernetes 1.21.1 kub…

页面设计都有哪些好用的工具推荐?

对于设计师来说&#xff0c;方便的页面设计工具和稳定的页面设计灵感也同样重要。 在今天的信息爆炸中&#xff0c;很容易找到页面设计工具&#xff0c;网上搜索有很多建议&#xff0c;但找到合适的页面设计工具并不那么简单。 本文推荐不容错过的9款页面设计工具 即时设计 …

【DevOps核心理念基础】3. 敏捷开发最佳实践

一、敏捷开发最佳实践 1.1 项目管理 1.2 需求管理 1.3 技术架构 1.4 技术开发 1.5 测试 二、敏捷开发最佳实践 2.1 敏捷开发的执行细节 三、全面的DevOps工具链 四、版本控制和协作开发工具 4.1 集中式版本控制工具 4.2 分布式版本控制工具 一、敏捷开发最佳实践 …

mysql的一些知识点或者说踩过的坑和想记住的内容

快速上传数据 这个应该是比inset into values更快的插入数据的办法了。 不过要求挺苛刻的&#xff0c;数据要整理成和表格一致&#xff0c;也就是说每条数据都是完整的一条&#xff0c;而不是一部分。 下面的示例我以***为分割符划分字段&#xff0c;以 \n来分割每条数据。 LO…

【atoi函数的功能介绍及使用与模拟实现——超详细版本】

atoi函数的功能介绍及使用与模拟实现——超详细版本 1.cplusplus网站介绍&#x1f4bb; 1.1atoi函数的功能介绍&#x1f4bb; 它的功能&#xff1a; 解析将其内容解释为整数的 C 字符串&#xff0c;该整数作为 类型的值返回。 该函数首先根据需要丢弃尽可能多的空格字符&…

java复习-eclipse开发工具使用

开发工具使用 项目文件结构 建立完成的项目目录中会自动创建有两个子目录&#xff1a; src&#xff1a;保存所有的 *.java 源文件bin&#xff1a;保存所有编译后的 *.class 程序文件&#xff0c;这些文件会自动进行编译处理 保存文件后&#xff0c;会自动进行编译。 快捷键…

无需专业技能,轻松创建个人博客:Cpolar+Emlog在Ubuntu上的搭建指南

文章目录 前言1. 网站搭建1.1 Emolog网页下载和安装1.2 网页测试1.3 cpolar的安装和注册 2. 本地网页发布2.1 Cpolar临时数据隧道2.2.Cpolar稳定隧道&#xff08;云端设置&#xff09;2.3.Cpolar稳定隧道&#xff08;本地设置&#xff09; 3. 公网访问测试总结 前言 博客作为使…

基于轻量级YOLOv5s开发构建隧道基建裂痕、脱落等缺陷问题检测系统

隧道内的定期检查与维护&#xff0c;对于及时发现和消除潜在的安全隐患有着重要的作用&#xff0c;基于人工的传统巡查方式不仅极为低效而且成本很高&#xff0c;将智能化的图像检测识别计数与实际的养护巡查场景相结合&#xff0c;开发构建智能AI检测识别系统是否可行&#xf…

C++QT day 5

实现一个图形类&#xff08;Shape&#xff09;&#xff0c;包含受保护成员属性&#xff1a;周长、面积&#xff0c; 公共成员函数&#xff1a;特殊成员函数书写 定义一个圆形类&#xff08;Circle&#xff09;&#xff0c;继承自图形类&#xff0c;包含私有属性&#xff1a;半…

element-table 行的拖拽更改顺序(无需下载sortableJs

样例展示&#xff1a;vueelement 通过阅读element文档我们发现element并不提供拖拽相关的api 本博客通过element提供的行类名 注册函数 实现行与行的拖拽 1.设置el-table 的行样式类名 这里是用的是 function <el-table:data"outputData":row-class-name&qu…

Codeforces Round 896 (Div. 2)题解

前言: 3 solved of 7 A、B、C,太菜了&#xff0c;写B题的时候&#xff0c;常数设成1e5了&#xff0c;一直卡在Test 4,没想到一直提示我TLE&#xff0c;没有提示RE&#xff0c;导致我浪费了很多时间在B题上&#xff0c;最后时间太晚了交了TLE了一发睡觉去了 A-Make It Zero …

SpringCloud:Feign实现微服务之间相互请求

文章目录 &#x1f389;欢迎来到Java学习路线专栏~SpringCloud&#xff1a;Feign实现微服务之间相互请求 ☆* o(≧▽≦)o *☆嗨~我是IT陈寒&#x1f379;✨博客主页&#xff1a;IT陈寒的博客&#x1f388;该系列文章专栏&#xff1a;Java学习路线&#x1f4dc;其他专栏&#xf…