当前位置: 首页 > news >正文

RUST编程语言入门基础2024

庄晓立,2024年3月。


Rust简介

A language empowering everyone to build reliable and efficient software.

Rust编程语言赋能所有人开发高可靠且高性能的软件。

性能

Rust is blazingly fast and memory-efficient: with no runtime or garbage collector, it can power performance-critical services, run on embedded devices, and easily integrate with other languages.

Rust能够编译出高性能运行且低内存占用的软件,没有运行时或垃圾收集器,适用于高性能服务、嵌入式设备,方便与其他语言集成。

可靠

Rust’s rich type system and ownership model guarantee memory-safety and thread-safety — enabling you to eliminate many classes of bugs at compile-time.

Rust拥有丰富的类型系统、所有者模型,保证内存安全和线程安全,让你在编译时消除许多类型的BUG。

开发效率

Rust has great documentation, a friendly compiler with useful error messages, and top-notch tooling — an integrated package manager and build tool, smart multi-editor support with auto-completion and type inspections, an auto-formatter, and more.

Rust有完善的文档,有友好的编译器输出实用的错误信息,有一流的工具:集成包管理器和编译工具,有多种编辑器且支持自动完成和类型审视,有代码格式化工具,等等。

安装Rust

推荐使用rustup安装Rust。

首先访问网站 https://rustup.rs/ ,下载 rustup-init.exe,然后按照提示逐步操作,即可完成安装Rust。

注意:在Windows操作系统下Rust需要依赖MSVC Build Tools(另有其他版本依赖gcc或clang)。

MSVC Build Tools可以在MS Visual Studio安装包内选装,确保选中模块“使用C++的桌面开发”(英文版“Desktop development With C++”)即可。

建议先安装MSVC Build Tools,然后再运行 rustup-init.exe 安装Rust,以便Rust自动找到MSVC链接器link.exe。

配置Rust开发和调试环境

针对VS Code编辑器,推荐使用两个插件:rust-analyzer,CodeLLDB。前者用于语法高亮和代码提示,后者用于调试。

安装方法:在VS Code的extensions界面搜索插件名称,点击install按钮即可。

Rust基础开发知识

Hello world

源文件hi.rs:

fn main() {println!("Hello world!");
}

编译:rustc hi.rs

运行:./hi

Playground

The Rust Playground, https://play.rust-lang.org/ , 用于在线编译和运行测试代码。

输出

println! 用于向stdout输出文本并换行。其首参数为格式文本(format string),其中{}{var}作为占位符。

let name = "liigo";
println!("hello {name}"); // 输出:hello liigo
let a = 123;
let b = "str";
println!("a={a} b={b}"); // 输出:a=123 b=str
println!("a={} b={}", a, b); // 同上

注释

// 单行注释
代码 // 行尾注释/*多行注释多行注释
*/
代码 /* 行中或跨行注释 */ 代码/// 外置文档注释(用于生成API文档),首行用一句话简要介绍。
/// 
/// 空一行后,详细说明其功能、参数、返回值、示例代码、Unsafe、Panic等。
/// 注释位于被注释的项目上方//! 内置文档注释(用于生成API文档),首行用一句话简要介绍。
//!
//! 空一行后,是详细说明。
//!这类文档注释主要用在模块源文件首部,把文档和代码放在一个文件内,方便维护。

下述两处位置的文档注释是等效的(区别仅位置不同,outer-doc-comments VS inner-doc-comments)

/// 外置
mod x {//! 内置
}

需要内置文档注释的场景,通常是文件模块顶部文档和根模块顶部文档,参见下文。

程序结构

Rust程序源码由一个或多个源文件(.rs)组成,但只有一个根源文件(通常命名main.rslib.rs)。

编译时只需给编译器(rustc)传入根源文件(无需传入其他源文件),编译器根据源码内部模块结构自动识别并载入其他源文件。

假设 main.rs 内有代码mod web;,当你使用命令行rustc main.rs编译时,编译器会尝试在如下位置寻找web模块的源文件:

  • #[path = "..."] 指定的目录和/或源文件(如果有的话)
  • web.rs
  • web/mod.rs

main.rslib.rs默认定义了根模块,其内部的mod web;定义了子模块web。子模块也可以有子模块,共同组成模块树,此模块树上每一个模块(包括根模块)内部都可以定义类型、函数等Items。

模块树定义了程序内部抽象结构,源文件树也能较好的体现模块结构。二者还可以灵活结合,实现定制的目录结构(主要依靠#[path = "..."])和模块结构(主要依靠pub use)。

定义模块

方式1:内联模块


/// 文档
mod mod1 {// 代码
}

方式2:文件模块

源文件main.rs:

mod mod2;

源文件mod2.rs:

//! 文档// 代码

以上定义的mod1和mod2均为当前模块的子模块。

数据类型

基础数据类型:

  • 逻辑/字符/文本:bool, char, str
  • 有符号整数:i8, i16, i32, i64, i128
  • 无符号整数:u8, u16, u32, u64, u128
  • 浮点数:f32, f64
  • Never: !

其他数据类型:

  • 序列相关:Tuple, Array, Slice
  • 自定义相关:Struct, Enum, Union
  • 函数相关:Functions, Closures
  • 指针相关:References, Raw pointers, Function pointers
  • 接口相关:Trait objects, Impl trait

参考:https://doc.rust-lang.org/stable/reference/types.html

定义变量

let a = 123;
let b = 123i8;
let c: i32 = 123;
let d = Some(123); // d: Option<i32>
let Some(x) = Some(123); // x: i32
let mut y = 0; // mut变量
y = 123; // 仅mut变量可以被赋值或被改变

定义类型

struct Counter {n: i32,
}impl Counter {pub fn new() -> Counter {Counter {n: 0,}}pub fn get(&self) -> i32 {self.n}pub fn add(&mut self, x: i32) {self.n += x;}
}#[test]
fn test1() {let mut counter = Counter::new();assert_eq!(counter.get(), 0);counter.add(1);assert_eq!(counter.get(), 1);counter.add(-2);assert_eq!(counter.get(), -1);
}

定义和实现接口

trait Inc {fn inc(&mut self);
}impl Inc for Counter {fn inc(&mut self) {self.add(1);}
}impl Clone for Counter {fn clone(&self) -> Self {Counter {n: self.get(),}}
}#[test]
fn test2() {let mut counter = Counter::new();counter.inc();counter.inc();let counter2 = counter.clone();assert_eq!(counter2.get(), 2);
}

流程控制

let a = 1;
if a == 1 {println!("a == 1");
} else {println!("a = {a}");
}enum Kinds { K1, K2, K3 }
let kind = Kinds::K1;
match kind {Kinds::K1 => { println!("K1"); }Kinds::K2 => { println!("K2"); }Kinds::K3 => { println!("K3"); }
}let nums = [1, 2, 3, 4, 5, 6, 7];
for n in nums {print!("{n} ");
}while cond {// code
}loop {// codeif cond {break;}
}

使用标准库

Rust程序默认静态链接标准库std,里面包含了很多常用模块/类型/接口/函数,可按需使用。

标准库在线文档:https://doc.rust-lang.org/stable/std/index.html

use std::fs::File;
use std::io::{BufRead, BufReader};fn main() {let file = File::open("./2023-09-15.log").unwrap();for line in BufReader::new(file).lines() {println!("{}", line.unwrap());}
}

使用Cargo和第三方库

使用Cargo创建项目:cargo init my_project (生成项目目录,含Cargo.toml src\main.rs等)

使用Cargo编译项目:cargo build (在项目目录内执行,下同)

使用Cargo运行项目:cargo run

添加第三方库依赖项:cargo add chrono (参见 chrono docs)

src\main.rs:

use chrono::Local;fn main() {println!("Hello, world! {}", Local::now());
}

Cargo.toml:

[package]
name = "my_project"
version = "0.1.0"
edition = "2021"# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html[dependencies]
chrono = "0.4.35"

其中最后一行是执行cargo add chrono时自动写入的。

测试

#[cfg(test)] mod tests定义测试模块,用#[test] fn定义测试函数,用cargo test启动测试。

pub fn add(left: usize, right: usize) -> usize {left + right
}#[cfg(test)]
mod tests {use super::*;#[test]fn it_works() {let result = add(2, 2);assert_eq!(result, 4);}
}

fn do_something() -> std::io::Result<()> {std::fs::File::open("./nosuchfile")?; // 因为某个错误提前返回println!("the main work");Ok(())
}fn main() {// 此处故意无视do_something()返回值,后果很严重:// 程序无故中途退出,无错误信息输出,也没法看调用栈,难以定位问题所在。// 正确的写法是`do_something().unwrap();`,`do_something().expect("...");`,或`do_something()?;`let _r = do_something();// 另一种无视返回值的写法是:`do_something().ok();`// 现实中一定要杜绝这类错误写法,因为后果真的很严重。// 为什么程序中途退出:因为代码控制流程提前返回了(?运算符具有提前返回的语义)// 为什么没有错误输出和调用栈:因为没有执行到panic!(unwrap/expect内部执行到panic!才会有相关输出)
}

相关文章:

RUST编程语言入门基础2024

庄晓立&#xff0c;2024年3月。 Rust简介 A language empowering everyone to build reliable and efficient software. Rust编程语言赋能所有人开发高可靠且高性能的软件。 性能 Rust is blazingly fast and memory-efficient: with no runtime or garbage collector, it can…...

Linux进程控制——Linux进程终止

前言&#xff1a;前面了解完前面的Linux进程基础概念后&#xff0c;我们算是解决了Linux进程中的一大麻烦&#xff0c;现在我们准备更深入的了解Linux进程——Linux进程控制&#xff01; 我们主要介绍的Linux进程控制内容包括&#xff1a;进程终止&#xff0c;进程等待与替换&a…...

利用IP地址查询解决被“薅羊毛”的方法

在互联网时代&#xff0c;随着各种网络诈骗手段的不断更新和演变&#xff0c;“薅羊毛”成为了一种常见的网络犯罪行为。其中&#xff0c;利用查询IP地址进行欺诈活动已经成为一种普遍的手段。当个人或组织的IP地址被不法分子查询后&#xff0c;可能会面临虚假注册、盗取个人信…...

Tomcat7+ 弱口令 后台getshell漏洞

1 漏洞背景 Tomcat 是一个流行的开源Web应用服务器&#xff0c;用于部署和运行Java Web应用程序。Tomcat 7 版本中存在一个安全隐患&#xff0c;即默认的管理员密码可能较弱或者未被修改&#xff0c;攻击者可以利用这一漏洞登录到Tomcat的管理后台&#xff0c;并上传恶意的WAR…...

香港虚拟主机哪里可以试用?用于企业建站的

香港虚拟主机适合个人、企业建站&#xff0c;包括外贸企业网站、个人博客网站、中小企业官网等&#xff0c;那么作为新手不知道哪家香港虚拟主机好用的时候&#xff0c;该如何找到可以试用的香港虚拟主机呢&#xff1f; 香港虚拟主机也称作香港空间、香港虚拟空间&#xff0c;…...

C# 集合(四) —— Set类

总目录 C# 语法总目录 集合四 Set 1. Set 1. Set 有 HashSet 和 SortedSet&#xff0c; 它们都不包含重复元素忽略添加重复值的请求无法根据位置访问元素使用Contains方法均使用散列查找&#xff0c;所以速度快 SortedSet 按照一定顺序保存元素&#xff0c;使用红黑树实现&a…...

C#实现多线程的几种方式

前言 多线程是C#中一个重要的概念&#xff0c;多线程指的是在同一进程中同时运行多个线程的机制。多线程适用于需要提高系统并发性、吞吐量和响应速度的场景&#xff0c;可以充分利用多核处理器和系统资源&#xff0c;提高应用程序的性能和效率。 多线程常用场景 CPU 密集型任务…...

C语言—控制语句

控制语句就是用来实现对流程的选择、循环、转向和返回等控制行为。 分支语句 if语句 基本结构 if(表达式) { 语句块1&#xff1b; } else { 语句块2&#xff1b; } 执行顺序&#xff1a; 如果表达式判断成立&#xff08;即表达式为真&#xff09;&#xff0c;则执行语句块…...

三. TensorRT基础入门-ONNX注册算子的方法

目录 前言0. 简述1. 执行一下我们的python程序2.转换swin-tiny时候出现的不兼容op的例子3. 当出现导出onnx不成功的时候&#xff0c;我们需要考虑的事情4. unsupported asinh算子5. unsupported deformable conv算子总结参考 前言 自动驾驶之心推出的 《CUDA与TensorRT部署实战…...

01、什么是ip、协议、端口号知道吗?计算机网络通信的组成是什么?

声明&#xff1a;本教程不收取任何费用&#xff0c;欢迎转载&#xff0c;尊重作者劳动成果&#xff0c;不得用于商业用途&#xff0c;侵权必究&#xff01;&#xff01;&#xff01; 目录 前言 计算机网络 网络ip地址 网络协议 网络端口号 前言 最近有个项目要用到相关文章…...

答题套路2 阅读理解 说明文某个词是否能去掉

观点 回答&#xff1a;不能 解词 某个词什么意思需要解释一下 反证法 如果去掉了&#xff0c;会怎么样 总结 使用这个词体现了说明文的科学性&#xff0c;严谨性...

Pytorch图像分类模型模型实时在线验证代码

1.训练并保存自己的模型 保存的模型格式为&#xff1a;XXX.pth torch.save(model, "./weight/last.pth")if best_acc <(validation_acc / len_val):torch.save(model, "./weight/best.pth")2.转化为ONNX格式 2.1环境安装&#xff08;window10&#x…...

Java高并发场景(银行转账问题)

最近面试问到了银行转账的高并发问题&#xff0c;回答的不是很理想&#xff0c;小编整理了下&#xff0c;题目大概如下&#xff1a; 有一张银行账号表&#xff08;银行账号字段、金额字段&#xff09;&#xff0c;A账号要给B账号转账&#xff0c;A扣款&#xff0c;B收款&#x…...

TypeScript 工具类型

这些工具类型是 TypeScript 提供的强大功能&#xff0c;用于操作和转换类型。下面是每个工具类型的简要说明和示例&#xff1a; 1、Record let value: Record<string, any> { name: "", age: 0, desc: [] }; let value2: { [key: string]: any } { name: &…...

[Kotlin]创建一个私有包并使用

1.创建Kotlin测试项目 在Android Studio或其他IDE中选择“Create New Project”。选择Kotlin和Gradle作为项目类型和构建系统。指定项目名称和位置&#xff0c;完成设置。 2.创建Android Library模块 官方文档&#xff1a;创建 Android 库 | Android Studio | Android De…...

鸿蒙应用开发者高级认证指南及参考资料整理(含详细参考答案)

如何报名鸿蒙应用开发者高级认证 报名链接:点击这里进行报名。报名步骤: 点击上述链接进入报名页面。选择“立即报名”。在课程内容中找到“HarmonyOS应用开发者高级认证”,点击进入。点击“参加考试”,随后即可开始考试。考试注意事项 实名认证:考试前,请务必完成实名认…...

数据匿名化技术

不同的数据匿名化技术可用于多种行业&#xff0c;旨在从数据流中获取有用的见解&#xff0c;同时确保满足数据保护标准和法规的合规要求。 数据脱敏&#xff08;Data Masking&#xff09; 数据脱敏&#xff0c;又称数据漂白、数据去隐私化或数据变形&#xff0c;指的是对数据集…...

HTML学习笔记汇总

整理一些常见问题的Links&#xff0c;不定期更新。 Html生成自定义函数的图形&#xff08;2024/5/10&#xff09;-CSDN博客 HTML中插入图片&#xff08;2024/5/10&#xff09;-CSDN博客 Html给网页加icon图标_html icon-CSDN博客...

初始JSVMP

1.初始JSVMP JSVMP是"JavaScript Virtual Machine Protection"的缩写&#xff0c;是一种前端代码虚拟化保护技术。它的核心思想是在JavaScript代码保护过程中引入代码虚拟化&#xff0c;将目标代码转换成自定义的字节码&#xff0c;这些字节码只有特殊的解释器才能识…...

【机器学习数据可视化-04】Pyecharts数据可视化宝典

一、引言 在大数据和信息爆炸的时代&#xff0c;数据可视化成为了信息传递和展示的关键手段。通过直观的图表和图形&#xff0c;我们能够更好地理解数据&#xff0c;挖掘其背后的信息。Pyecharts&#xff0c;作为一款基于Python的数据可视化库&#xff0c;凭借其丰富的图表类型…...

RestClient

什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端&#xff0c;它允许HTTP与Elasticsearch 集群通信&#xff0c;而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级&#xff…...

浅谈 React Hooks

React Hooks 是 React 16.8 引入的一组 API&#xff0c;用于在函数组件中使用 state 和其他 React 特性&#xff08;例如生命周期方法、context 等&#xff09;。Hooks 通过简洁的函数接口&#xff0c;解决了状态与 UI 的高度解耦&#xff0c;通过函数式编程范式实现更灵活 Rea…...

TDengine 快速体验(Docker 镜像方式)

简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能&#xff0c;本节首先介绍如何通过 Docker 快速体验 TDengine&#xff0c;然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker&#xff0c;请使用 安装包的方式快…...

Linux链表操作全解析

Linux C语言链表深度解析与实战技巧 一、链表基础概念与内核链表优势1.1 为什么使用链表&#xff1f;1.2 Linux 内核链表与用户态链表的区别 二、内核链表结构与宏解析常用宏/函数 三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势5.1 插入效率5.2 安全…...

基于ASP.NET+ SQL Server实现(Web)医院信息管理系统

医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上&#xff0c;开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识&#xff0c;在 vs 2017 平台上&#xff0c;进行 ASP.NET 应用程序和简易网站的开发&#xff1b;初步熟悉开发一…...

条件运算符

C中的三目运算符&#xff08;也称条件运算符&#xff0c;英文&#xff1a;ternary operator&#xff09;是一种简洁的条件选择语句&#xff0c;语法如下&#xff1a; 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true&#xff0c;则整个表达式的结果为“表达式1”…...

高危文件识别的常用算法:原理、应用与企业场景

高危文件识别的常用算法&#xff1a;原理、应用与企业场景 高危文件识别旨在检测可能导致安全威胁的文件&#xff0c;如包含恶意代码、敏感数据或欺诈内容的文档&#xff0c;在企业协同办公环境中&#xff08;如Teams、Google Workspace&#xff09;尤为重要。结合大模型技术&…...

Spring Boot面试题精选汇总

&#x1f91f;致敬读者 &#x1f7e9;感谢阅读&#x1f7e6;笑口常开&#x1f7ea;生日快乐⬛早点睡觉 &#x1f4d8;博主相关 &#x1f7e7;博主信息&#x1f7e8;博客首页&#x1f7eb;专栏推荐&#x1f7e5;活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...

【Go语言基础【13】】函数、闭包、方法

文章目录 零、概述一、函数基础1、函数基础概念2、参数传递机制3、返回值特性3.1. 多返回值3.2. 命名返回值3.3. 错误处理 二、函数类型与高阶函数1. 函数类型定义2. 高阶函数&#xff08;函数作为参数、返回值&#xff09; 三、匿名函数与闭包1. 匿名函数&#xff08;Lambda函…...

STM32HAL库USART源代码解析及应用

STM32HAL库USART源代码解析 前言STM32CubeIDE配置串口USART和UART的选择使用模式参数设置GPIO配置DMA配置中断配置硬件流控制使能生成代码解析和使用方法串口初始化__UART_HandleTypeDef结构体浅析HAL库代码实际使用方法使用轮询方式发送使用轮询方式接收使用中断方式发送使用中…...