Rust语法:变量,函数,控制流,struct

文章目录

    • 变量
      • 可变与不可变变量
      • 变量与常量
      • 变量的Shadowing
      • 标量类型
        • 整数
      • 复合类型
    • 函数
      • 控制流
        • if else
        • loop & while
        • for in
    • struct
      • struct的定义
      • Tuple Struct
      • struct的方法与函数

变量

可变与不可变变量

Rust中使用let来声明变量,但是let声明的是不可变变量,如果想要可变,则需要加上mut关键字

fn main(){let x = 10;x = x + 1; //报错,因为x是不可变类型let mut y = 11;y = y + 1; //可行
}

变量与常量

常量与不可变变量一样都是不能被修改的,但是他与不可变变量有很多区别。

  1. 常量用const声明,且必须标注其类型
  2. 常量不能加mut修饰
  3. 常量可以在任何作用域内声明(包括全局)
  4. 常量只可以绑定在常量表达式中,无法绑定在函数的调用结果或者只能在运行时才能计算出的值。
  5. 在场许运行期间,长廊在其作用域内一直有效。

常量命名规范:全大写字母+下划线分割(不符合规范rust编译器会警告)

const MAX_POINT = 10000;
fn main(){
}

变量的Shadowing

Rust允许用户在一个作用域内重复的声明一个同名变量,并且可以是不同的类型的,而后声明的变量会覆盖前面声明的变量,这叫做变量的shadowing

fn main(){let x = 100;let x = "Test"; // 此时在对x进行操作,x的值就是"Test"let number = "123123";let number = number.trim().parse(); //转化为数字//上述shadowing就使得通用一个number的变量名,但是却做到了类型转换。
}

标量类型

Rust是一个强类型的静态语言,这意味着在编译时编译器就需要明确的知道每个变量的类型,而不是像Py一样,“变量的类型是动态可变的”。

而上述的代码没有指定类型,只使用了let,是因为Rust的编译器可以自行推断出变量的类型(根据返回值,上下文,调用情况)。而有时情况过于复杂时便无法推断,便需要使用者自行标注出类型。

整数

整数类型如下:
在这里插入图片描述
可以看到分类无符号和有符号类型,并且每个类型都标清楚了占多少字节,最后一个isize类型表示的是CPU位数长度的整数类型(一个机器字长),与电脑硬件有关。

如下面代码所示,在变量后面加冒号在家类型就可以强制显示的的表明变量的类型。

fn main(){let x: i8 = 18;let y: u32 = 100;
}

在这里插入图片描述
整数字面值如上:
Rust允许在数字之间加下划线用于增加可读性。其中十六进制以0x开头,八进制以0o开头,二进制以0b开头。
而字节类型需要在字符串前加一个b。

Rust允许在数值后面加上类型来标注这个数字的类型

fn main(){let x = 1002u32let y = 10010010i32let z = 0b100100let a = 0xffa0let b = b'B'
}

在这里插入图片描述
Rust的int默认值是32,浮点数默认值是64Bytes。如果整数类型发生了溢出,那么程序就会panic,如果在发布模式下编译则不会检查溢出。Rust的溢出会进行环绕操作,即对可取的最大值取余。
在这里插入图片描述
布尔类型则是有两个值,一个是true,一个是false占两个字节

fn main(){let x: bool = true;
}

字符类型用来描述语言中最基础的单个字符,占四个字节,使用的值是Unicode表值。

fn main(){let x: char = '你';let u: char = '🙂';
}

复合类型

Rust提供了两种复合类型,一个是Tuple,一种是数组。
Tuple的创建遵循以下规则:
在这里插入图片描述

fn main(){let x: (i32, char, f32) = (2003, 'a', 0.3);println!("{} {} {}", x.0, x.1, x.2);
}

对于元组可以使用点+索引的形式来得到元素,元组是定长的,你可以认为它类似于C的struct的简化版。

元组还可以进行拆包,其过程如下:

fn main(){let x: (i32, char, f32) = (2003, 'a', 0.3);let (a, b, c ) = x;
}

另一个数据类型,数组则是定长,且使用[]来进行定义和创建

fn main(){let x: [i32; 5] = [1, 2, 3, 4, 5]; // 创建一个i32类型,长度为5的数组let y = [5; 4];// 创建4个i32类型值为5,长度为4的数组let z = ["xxx", "yyy"]; //创建两个str类型的数组
}

上述需要注意的是let y = [5; 4];这种写法相当于是创建一个重复为5,长度为4的数组

函数

rust的函数的格式为:

fn 函数名(参数: 类型) -> 返回值{函数体;
}
fn main(){let x = test();
}fn test(){println!("Test");
}

上述的test的返回值是()。

fn main(){let _x = test(32);
}fn test(number: i32) -> (){println!("Test number is {}", number);
}

Rust的函数体由Statement和Expression来构成,其中Statement指的是像let x = 10;这类的语句,而Expression则是x + 3, x == 5这样具有返回值的表达式。

Rust默认最后一个表达式即为返回值(或者函数题的值),如果没有则默认值为()

fn main(){let x = test(10);println!("Test number is {}", x);
}fn test(number: i32) -> i32{5 + number //注意,5 + number后面没有分号,否则将会被视为一个语句
}

这个函数体还可以作为变量的值来传递

fn main(){let x = {let mut _y = 11;_y * 3};println!("{}", x)
}

上述x的的值是33,如果函数体最后一个语句没有返回值,则会得到()

控制流

与Rust控制流相关的有loop,while,for in的循环语句和if else,match的判断语句。其中match涉及到枚举不在这里记录,放在枚举那里。

if else

if和else就类似于C语言,当只有一个单独的语句时可以不用最外层的括号

fn main(){let x = 10;if x > 5 {println!("大于5");}else if x == 5 {println!("小于5");}else {println!("小于5");}
}

三元运算符,有点类似于python与C的结合体,例子如下

if 条件 {结果1} else {结果2}

fn main(){let x = if 5 > 3 {5} else {3};println!("x is {}", x);let y = if x != 5 {x * 2}else{x - 3};println!("y is {}", y);
}
/*Compiling hello_world v0.1.0 (E:\RustProject\Hello_World)Finished dev [unoptimized + debuginfo] target(s) in 0.69sRunning `target\debug\hello_world.exe`
x is 5
y is 2
*/

loop & while

loop的用法就是相当于while true,也就是loop内的语句会被不停地循环,直到遇到break为止。
用法如下:

fn main(){let mut x = 0;loop{x += 1;if x > 10{break;}}println!("x is {}", x);
}

而对于while循环则是和C和Py一样,break和continue语句也是同样的道理。

while 条件{}

fn main(){let mut x = 0;while x <= 10 {x += 1;}println!("x is {}", x);
}

for in

for in则是类似于py的for in集合的模式,in后面需要跟一个可以迭代的类型例如数组。
需要注意的是此时tmp是&i32类型,也就是说它的类型是确定的,没法for in一个多种类型的Tuple。

fn main(){let x = [3, 4, 5, 6];for tmp in x.iter(){ //iter方法得到x的迭代器println!("{}", tmp);}
}
/*Compiling hello_world v0.1.0 (E:\RustProject\Hello_World)Finished dev [unoptimized + debuginfo] target(s) in 1.07sRunning `target\debug\hello_world.exe`
3
4
5
6
*/

对于计数之类的需求,Rust提供了Range的方法,可以使用a…b来构造一个a+1,a+2…, b-2, b-1的序列来进行遍历,如下:

fn main(){for x in 3..10{println!("{}", x);}
}
/*Compiling hello_world v0.1.0 (E:\RustProject\Hello_World)Finished dev [unoptimized + debuginfo] target(s) in 1.03sRunning `target\debug\hello_world.exe`
3
4
5
6
7
8
9
*/

struct

struct的定义

Rust的struct定义如下:

struct 名称{
变量1: 类型,
变量2: 类型…
}

struct Rectangle{width: u32,length: u32
}

而struct的初始化则是使用名字+变量名:值的形式初始化,注意,struct不允许有字段为空值,也就是说需要全部值都初始化

    let re = Rectangle{width: 10,length: 19};

而这些值的访问就类似于C的struct,直接用点+对应的字段即可。

struct也可以设置为mut,而对于struct来说,一旦设置为mut,则里面每个值都必须要是mut,也就是说都是可变的。

    let mut re = Rectangle{width: 10,length: 19};re.width = 100;

当有变量名与struct内部定义的变量名同名时,可以省去冒号进行初始化

struct Rectangle{width: u32,length: u32
}fn main(){let width = 9;let mut re = Rectangle{width, // 省去了冒号,因为width同名length: 19};
}

当想要对struct进行更新时,有一种简单的简写操作,如下:

    let width = 9;let mut re = Rectangle{width, length: 19};let re2 = Rectangle{width: 100,..re //re表示,剩下的字段的值与re的剩余字段的值相同};

Tuple Struct

Tuple Struct是一个特殊的Tuple,他可以想

struct的方法与函数

对于一个struct,它拥有对应的方法和函数,而对于方法则是应用于struct的上下文中的,可以获取和修改具体的struct的值。而函数则不能,他只是与某种struct关联到了一起而已。
使用impel关键字来为struct绑定方法和函数。

第一个参数带有self关键字就是方法,而不带有则是函数

struct Rectancle{width: u32,length: u32,
}impl Rectancle {//为Rectangle绑定函数和方法fn area(&self) -> u32{//绑定一个方法&self表示Rectangle结构体本身self.width * self.length //返回面积}
}fn main(){let y = Rectancle{width: 10,length: 15};println!("Area is {}", y.area());
}

下面是绑定一个函数例子

struct Rectancle{width: u32,length: u32,
}impl Rectancle {fn area(&self) -> u32{self.width * self.length}fn make_square(size: u32) -> Rectancle { //构造一个正方形Rectancle { width: (size), length: (size) }}
}fn main(){let sq = Rectancle:: make_square(10);//通过使用::的方式来调用函数println!("Area is {}", sq.area());
}

需要注意,每个struct允许拥有多个impel的模块。

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

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

相关文章

Golang自定义类型与类型别名

type myInt int32 与 type myInt int32&#xff0c;概念并不相同 自定义类型&#xff1a;type myInt int32 通过这种方式定义的类型是一个全新的类型&#xff0c;这个新类型与int32有相同的底层结构&#xff0c;但是却与int32类型不兼容。 type myInt int32var a int32 5 var…

双色球彩票系统---(java实现)

双色球彩票系统&#xff1a;需求&#xff1a;投注号码由6个红色号码和1个蓝色球号码组成。红色球号码从1-33中选择&#xff0c;蓝色球号码从1-16当中选择 * 红 蓝 * 一等奖 6 1 * 二等奖 6 0 * 三等奖 5 1 * 四等奖 5 0 * 4 1 * 五等奖 4 0 * …

Blazor简单教程(1.1):Razor基础语法

文章目录 前言基本文件配置引入Layout组件 语法介绍pagecodeRazor 语法[ 显式表达和隐式表达](https://learn.microsoft.com/zh-cn/aspnet/core/mvc/views/razor?viewaspnetcore-7.0#explicit-razor-expressions) 绑定简单绑定双向绑定带参数的函数绑定 依赖注入 前言 Blazor…

synchronized使用

目录 问题描述 1 锁方法 2 锁代码块 3 锁某个类 4 静态方法上的synchronized 当我们处理多线程处理同步问题的时候就会用到synchronized这个关键字&#xff0c;下面介绍下synchronized的四种用法。 问题描述 介绍之前我们先来看下&#xff0c;在java 多线程中 如果没有线…

leetcode1. 两数之和

题目&#xff1a;leetcode1. 两数之和 描述&#xff1a; 给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标值 target 的那 两个 整数&#xff0c;并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是&#xff0c;数组中…

QT:UI控件(按设计师界面导航界面排序)

基础部分 创建新项目&#xff1a;QWidget&#xff0c;QMainWindow&#xff0c;QDialog QMainWindow继承自QWidget&#xff0c;多了菜单栏; QDialog继承自QWidget&#xff0c;多了对话框 QMainWindow 菜单栏和工具栏&#xff1a; Bar: 菜单栏&#xff1a;QMenuBar&#xff0…

A Survey for In-context Learning

A Survey for In-context Learning 摘要&#xff1a; 随着大语言模型(LLMs)能力的增长&#xff0c;上下文学习(ICL)已经成为一个NLP新的范式&#xff0c;因为LLMs仅基于几个训练样本让内容本身增强。现在已经成为一个新的趋势去探索ICL来评价和extrapolate LLMs的能力。在这篇…

微服务06-分布式事务解决方案Seata

1、Seata 概述 Seata事务管理中有三个重要的角色: TC (Transaction Coordinator) - **事务协调者:**维护全局和分支事务的状态,协调全局事务提交或回滚。 TM (Transaction Manager) - **事务管理器:**定义全局事务的范围、开始全局事务、提交或回滚全局事务。 RM (Resourc…

Java地图专题课 基本API BMapGLLib 地图找房案例 MongoDB

本课程基于百度地图技术&#xff0c;由基础入门开始到应用实战&#xff0c;适合零基础入门学习。将企业项目中地图相关常见应用场景的落地实战&#xff0c;包括有地图找房、轻骑小程序、金运物流等。同时讲了基于Netty实现高性能的web服务&#xff0c;来处理高并发的问题。还讲…

ttf-dejavu fontconfig字体

ttf-dejavu fontconfig是验证码&#xff0c;pdf&#xff0c;excel时需要用到的字体 编辑dockerfile&#xff0c;先切换国内镜像源&#xff0c;默认alpinelinux是国外源&#xff0c;下载包会很慢 vim Dockerfile FROM alpine:latest RUN sed -i s/dl-cdn.alpinelinux.org/mirr…

【创建型设计模式】C#设计模式之原型模式

原型模式是一种创建型设计模式&#xff0c;它通过复制现有对象来创建新对象&#xff0c;而无需通过实例化的方式。它允许我们使用已经存在的对象作为蓝本&#xff0c;从而创建新的对象&#xff0c;这样可以避免重复初始化相似的对象&#xff0c;提高了对象的创建效率。 现在给…

Sentinel

1、熔断降级限流 熔断 A服务调用B服务的某个功能&#xff0c;由于网络不稳定、B服务卡机等问题&#xff0c;导致功能时间超长。如果这样子的次数太多&#xff0c;我们就可以直接将B断路&#xff08;A不再请求B接口&#xff09;&#xff0c;凡是调用B服务的直接返回降级数据&a…

13-数据结构-串以及KMP算法,next数组

串 目录 串 一、串&#xff1a; 二、串的存储结构&#xff1a; 三、模式匹配 1.简单模式匹配&#xff08;BF算法&#xff09; 2.KMP算法 2.1-next&#xff08;j&#xff09;数组手工求解 2.2-nextval&#xff08;j&#xff09;数组手工求解 一、串&#xff1a; 内容受…

JVM垃圾回收篇-垃圾回收算法

JVM垃圾回收篇-垃圾回收算法 标记清除&#xff08;Mark Sweep&#xff09; 概念 collector指的就是垃圾收集器。 mutator是指除了垃圾收集器之外的部分&#xff0c;比如说我们的应用程序本身。 mutator的职责一般是NEW(分配内存)、READ(从内存中读取内容)、WRITE(将内容写入内…

将多个单独的 Excel 文件合并成一个,并添加标题行

要将多个单独的 Excel 文件合并成一个&#xff0c;并添加标题行&#xff0c;可以使用 Python 的 pandas 库。以下是一个示例代码&#xff0c;假设要合并的 Excel 文件都在同一个文件夹中&#xff1a; import os import pandas as pd # 指定文件夹路径 folder_path path/to/fo…

vscode搭建c语言环境问题

c语言环境搭建参考文章:【C语言初级阶段学习1】使用vscode运行C语言&#xff0c;vscode配置环境超详细过程&#xff08;包括安装vscode和MinGW-W64安装及后续配置使用的详细过程&#xff0c;vscode用户代码片段的使用&#xff09;[考研专用]_QAQshift的博客-CSDN博客 问题如下:…

[C++ 网络协议] 套接字和地址族、数据序列

目录 1. 套接字 1.1 在Linux平台下构建套接字 1.1.1 用于接听的套接字(服务器端套接字) 1.1.2 用于发送请求的套接字(客户端套接字) 1.2 在Windows平台下构建套接字 1.2.1 Winsock的初始化 1.2.2 用于接听的套接字(服务器端套接字) 1.2.3 用于发送请求的套接字(客户端套…

pytest框架快速进阶篇-pytest前置和pytest后置,skipif跳过用例

一、Pytest的前置和后置方法 1.Pytest可以集成unittest实现前置和后置 importunittestimportpytestclassTestCase(unittest.TestCase):defsetUp(self)->None:print(unittest每个用例前置)deftearDown(self)->None:print(unittest每个用例后置)classmethoddefsetUpClass…

jmeter中用户参数和用户定义的变量的区别

如果使用jmeter做过参数化的人都知道&#xff0c;参数化的方式有多种&#xff0c;其中一种就是使用用户定义的变量&#xff0c;还有一种是使用用户参数。那么&#xff0c;这两个有什么异同呢&#xff1f; 一、先说相同的点&#xff1a; 1、都可以参数化&#xff0c;以供sample…

allure测试报告

使用pytest结合Allure进行测试报告生成的简单教程 allure测试报告 Allure基于Java开发&#xff0c;因此我们需要提前安装Java 8或以上版本的环境。 ◆安装allure-pytest插件在DOS窗口输入命令“pip3 install allure-pytest”&#xff0c;然后按“Enter”键。 下载安装Allure…