首页 > 其他分享 >关于Rust的简单总结(一)

关于Rust的简单总结(一)

时间:2023-12-12 19:22:49浏览次数:38  
标签:总结 count 函数 let fn 简单 main Rust String

0. 前言

这是一个关于Rust的简单总结。(待续)

资料

Rust介绍

[[Rust]] 程序设计语言的本质实际在于 赋能empowerment):无论你现在编写的是何种代码,Rust 能让你在更为广泛的编程领域走得更远,写出自信。(这一点并不显而易见)

Cargo介绍

[[Cargo]] 是 Rust 的构建系统和包管理器。大多数 Rustacean 们使用 Cargo 来管理他们的 Rust 项目,因为它可以为你处理很多任务,比如构建代码、下载依赖库并编译这些库。


1. Hello World!

Rust

  • 编译 main.rs文件rustc main.rs
  • 运行 main.exe程序main.exe

Cargo

  • 新建 Cargo程序Cargo new Project Name
  • 构建 Cargo程序Cargo build
  • 构建并运行Cargo程序Cargo run

2. 变量可变性

  • 不可变变量 let x = 5;
  • 可变变量 let mut x = 5;
  • 常量 const THREE_HOURS_IN_SECONDS: u32 = 60 * 60 * 3;

3. 数据类型

标量类型

  • 整数型let x: u32 = 1;
  • 浮点型 :let x: f32 = 3.0; 注:f32:单精度浮点数,f64:双精度浮点数
  • 字符类型 :let x:char = 'ℤ';
  • 布尔型 :let x: bool = false; 注: TureFalse

复合类型

  • 元组型(Tuple):let tup: (i32, f64, u8) = (500, 6.4, 1);

元组的使用:
let x = (500, 6.4, 1);
let five_hundred = x.0; x.0的值为500
let one = x.2;

  • 数组型(array):let a = [1, 2, 3, 4, 5];

数组的使用:
let a = [1, 2, 3, 4, 5];
let a:[i32; 5] = [1, 2, 3, 4, 5]; 指定数组的类型和长度
let x = a[0] a[0]的 值为1


4.函数

表达式

//Rust中的表达式是指由{ }包裹的语句。
fn main(){
let y = { 
	let x = 3; 
	x + 1        //注意 `x+1` 这一行在结尾没有分号 
	}; 
println!("The value of y is: {y}"); 
}

函数

//返回值的函数
fn main() { 
let x = plus_one(5); 
println!("The value of x is: {x}"); 
} 
fn plus_one(x: i32) -> i32 { 
x + 1   //这里没有分号 ,函数体{}内是一个表达式,表达式的值作为函数的返回值
}

注:函数的参数必须指定数据类型 ,函数值利用表达式语法,表达式的值作为函数的返回值。


5.控制流

IF语句

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"); }

WHILE语句

while number != 0 { println!("{number}!"); number -= 1; }

FOR语句

let a = [10, 20, 30, 40, 50]; 
for element in a { println!("the value is: {element}"); }

LOOP语句

  • loop语句,无条件一直循环,通过输入Ctrl + C终止条件。
loop { println!("again!"); }
  • break关键字传参
let mut counter = 0;
loop { 
counter += 1; 
if counter == 10 {
	break counter * 2;   // break关键字传递参数 
	} 
};
  • break关键字标记
//break标记
fn main() {
let mut count = 0
'counting_up: loop {//标记处
	println!("count = {count}");
	let mut remaining = 10;
	loop {
		println!("remaining = {remaining}");
		if remaining == 9 { break; }//没有标记,跳出的是当前loop
		if count == 2 { break 'counting_up; }//通过标记 跳出的是最外层loop
		remaining -= 1; 
		} 
	count += 1;
	}
println!("End count = {count}");
}

6.所有权

所有权:

  • Rust中每一个值都有一个所有者(owner)。
  • 值在任一时刻有且仅有一个所有者。
  • 当所有者离开作用域时,这个值会被丢弃。

栈(Stack)与堆(Heap)

栈:存放的数据都必须占用已知且固定的大小。
堆:存放的数据大小未知或大小可能变化的数据。

数据交互方式

移动:

let x = 5;  //x的值是放入了栈中的。 
let y = x;  //数据移动时,简单数据类型x不会失效。(复制了一份数据)
let s1 = String::from("hello"); //s1的值是存在堆中的。
let s2 = s1; //数据移动时,s1的值给了s2,s1失效。(堆中数据不会复制)

克隆:

let  s1 = String::from("hello"); //s1的值是存在堆中的。
let  s2 = s1.clone();//数据克隆,s1的值在堆中复制了一份,s1有效。

所有权与函数与返回值

fn main{
let s = String::from("hello");  //s 进入作用域
takes_ownership(s);             //s 的值移动到函数里

let x = 5;                      //s 进入作用域
makes_copy(x);                  //x应该移动函数里,但 i32是Copy的,
                                //所以后面可以继续使用x
}//这里,x先移出了作用域,然后是s。但因为s的值已被移走。
fn main{
let s1 = gives_ownership(); //gives_ownership 将返回值转移给s1

let s2 = String::from("hello");//s2进入作用域

let s3 = takes_and_gives_back(s2);//s2 被移动到 takes_and_gives_back函数中
					         	  //它将返回值给s3。
}//这里,s3移出作用域并被丢弃,s2也将移动作用域,但已经被移走,所以什么也不会发生,s1离开作用域被丢弃。

引用与借用

  • 引用: & 例:let len = calculate_length(&s1);
  • 解引用:*
  • 借用:创建引用的行为称为借用,借用不会获取其所有权(离开作用域时,指向的值不会被丢弃。)
  • 可变引用:
let mut s = String::from("hello")
let r1 = &mut s; //创建一个内容可以被改变的引用
  • 引用的规则:
    • 在任意给定时间,要么只能有一个可变引用,要么只能有多个不可变引用
    • 引用必须总是有效的。

字符串slice

let s = String::from("hello world");
let hello  =&s[0..5]; // 对于字符串的部分引用。  [0..5] 也可以写成[..5]
let world = &s[6..11];  //[6..len] 也可以写成 [6..]

7.结构体

结构体示例

//User的结构体
struct User {
active: bool,
username: String,
email: String,
sign_in_count: u64,
}

fn main() { 
let mut user1 = User { 
	active: true,
	username: String::from("someusername123"),
	email:String::from("[email protected]"),
	sign_in_count: 1,
	 }; //此处 是结构体User的一个实例

	user1.email = String::from("[email protected]");
	//此处是对实例的一个使用,更改实例User1里email成员的值。
}

使用字段初始化简写语法

struct User {
    active: bool,
    username: String,
    email: String,
    sign_in_count: u64,
}
// build_user 函数使用了字段初始化简写语法,因为 username 和 email 参数与结构体字段同名
fn build_user(email: String, username: String) -> User {
    User {
        active: true,
        username,
        email,
        sign_in_count: 1,
    }
}
fn main() {
    let user1 = build_user(
        String::from("[email protected]"),
        String::from("someusername123"),
    );
}

使用结构体更新语法从其他实例创建实例

struct User {
    active: bool,
    username: String,
    email: String,
    sign_in_count: u64,
}
fn main() {
    let user1 = User {
        email: String::from("[email protected]"),
        username: String::from("someusername123"),
        active: true,
        sign_in_count: 1,
    };
    //这里  user2直接从user1的实例中取得了部分的数据。
    let user2 = User {
        active: user1.active,
        username: user1.username,
        email: String::from("[email protected]"),
        sign_in_count: user1.sign_in_count,
    };
}

无命名字段结构体

struct Color(i32, i32, i32);
struct Point(i32, i32, i32);

fn main() {
    let black = Color(0, 0, 0);
    let origin = Point(0, 0, 0);
}

注:虽然这ColorPoint类型都由三个 i32 值组成,但是一个获取 Color 类型参数的函数不能接受 Point 作为参数。因为它们是不同的元组结构体的实例。

结构体中的方法

  • 关联函数:使用impl关键字将函数与结构体绑定,这些函数被称作结构体的关联函数(注:关联函数经常被用作返回一个结构体新实例的构造函数,如new(),类似于Java,C++中的静态方法。)
  • 方法:关联函数的第一个参数是self的函数被称作方法

关联函数的使用:结构体名 :: 关联函数名(参数)
示例:let sq = Rectangle::square(3);

方法的使用:实例名.方法名(参数)
示例:rect1.area()

关联函数示例:

#[derive(Debug)]
struct Rectangle {
    width: u32,
    height: u32,
}

impl Rectangle {
	//这里 square 的第一个参数不是self,因此是关联函数。
    fn square(size: u32) -> Self {
        Self {
            width: size,
            height: size,
        }
    }
}

fn main() {
    let sq = Rectangle::square(3);//关联函数的使用
}

方法的示例:

//这是一个结构体
struct Rectangle {
    width: u32,
    height: u32,
}
// impl:impl块中的内容都与Rectangle相关联。
impl Rectangle {
    fn area(&self) -> u32 {
        self.width * self.height
    }
}

fn main() {
    let rect1 = Rectangle {
        width: 30,
        height: 50,
    };

    println!(
        "The area of the rectangle is {} square pixels.",
        rect1.area()   //这里,使用了rect1的area()方法。
    );   
}

X. 相关表

整数型相关

长度 有符号 无符号
8-bit i8 u8
16-bit i16 u16
32-bit i32 u32
64-bit i64 u64
128-bit i128 u128
arch isize usize
数字字面值 例子
Decimal (十进制) 98_222
Hex (十六进制) 0xff
Octal (八进制) 0o77
Binary (二进制) 0b1111_0000
Byte (单字节字符)(仅限于u8) b'A'

标签:总结,count,函数,let,fn,简单,main,Rust,String
From: https://www.cnblogs.com/TianyiLi-Tone/p/17897637.html

相关文章

  • 项目经理的年终总结没写好,一年全白干
    项目经理年终吐槽大会:又到年底了,办公室的项目经理们好不容易能聚在一起,大家在交流工作时,对这一年的工作状态简要吐槽了几句。每一句都堪称经典,但无不透露出各种心酸。a)     项目经理小王:感情状态——继续单身,根本没空谈恋爱;身材体重——过劳肥。b)     项目经理小刘:每......
  • python中x[:] x[::]用法总结
    X[:,0]#二维数组取第1维所有数据X[:,1]#第2列X[0,:]#第1行X[3,:]#第三行X[1:4,:]#第一二三行总结一下:无论是左边还是右边逗号都要靠近冒号:如果冒号:的左边或者右边还有冒号,这时候就说明其中一个冒号代表的是范围(eg:1:5从1到4)如果冒号:左边或者右边没有任何东西,那么这......
  • 软件工程UML总结
    个人总结软件工程中UML的各类图绘制繁多复杂,这里为大家总结,有错请指正。1.用例图是用例模型的一部分,用例模型还包括用例规约,用于对用例图中为展示出来的细节进行规定,用例图由参与者、用例以及它们之间的关系构成,用于描述系统功能。例如我绘制的以下用例图:2.顺序图分为系统顺序......
  • dioxus 桌面渲染简单说明
    dioxus是基于rust开发的支持跨平台应用开发的框架,对于桌面的支持是利用了tauri提供的一些工具包目前来说是利用了tao以及wry参考使用添加引用核心是添加desktop的cargo cargoadddioxuscargoadddioxus-desktop代码//此处是......
  • postman 简单使用,设置全局请求头,登入后自动替换全局token
    postman简单使用,设置全局请求头,登入后自动替换全局token背景1.使用postman没次请求需要带上请求头(每个请求都加一下麻烦),2.token有过期时间,没次都要替换(人为替换全局变量麻烦),直接调用一下登入请求直接替换环境1.设置集合下面每个请求全局请求tokenpm.request.addH......
  • 全网最全,MySQL 增删改查高级命令硬核总结
    MySQL入门教程:全网最全,MySQL增删改查高级命令硬核总结原创 白鹿第一帅 白鹿第一帅 2023-12-0507:00 发表于四川文章目录前言一、连接到MySQL数据库1.1、连接到本机上的MySQL1.2、连接到远程主机上的MySQL二、退出MySQL命令三、修改MySQL密码3.1、先给roo......
  • easyYapi 简单使用 ,一次只导出一个方法,swagger 注解生效,md 文档
    easyYapi简单使用,一次只导出一个方法,swagger注解生效,md文档有时候开放平台需要写文档,这个时候给yapi和swagger就不太友好,导出md,在导入smartdoc或者自己的md线上,其他3方的文档库语雀啥的就会好很多。1.第一步安装idea插件4.设置配置信息3.swagger......
  • SPI通信协议总结
    我们将讨论最常见协议的基础:串行外设接口(SerialPeripheralInterface,SPI)SPI,I2C和UART比USB,以太网,蓝牙和WiFi等协议要慢很多,但它们更简单,使用的硬件和系统资源也更少。SPI,I2C和UART非常适用于微控制器之间以及不需要传输大量高速数据的微控制器与传感器之间的通信。串行通信 ......
  • SQLServer备份恢复的总结-同名恢复与异名恢复
    SQLServer备份恢复的总结前言GUI搞一把.命令行太多了也没人看自己还能省点心备份备份数据库建议一定要选择:备份选项中的压缩->压缩备份历史经验一个7.6G的数据库能够压缩到1.5G压缩比还是已非常可观的.同名恢复1.可以使用sa登录2.创建一个database,同名......
  • 写了一个flinkcdc的简单demo,大概说一下实现过程和建议点
    架构图大致如下:版本信息大致如下,具体版本信息根据自己的需求进行调整即可:oracle:19cflinkcdc:2.4.0kafka:3.1.2flink:1.15.4mysql:8.0.27springboot:2.5.6实现需求:1.使用flinkcdc采集oracle中的数据(历史数据+增量数据:含增删改)同步至kafka的某个topic中2.使用flink消费kafka中......