当前位置: 首页 > 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;凭借其丰富的图表类型…...

51c自动驾驶~合集58

我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留&#xff0c;CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制&#xff08;CCA-Attention&#xff09;&#xff0c;…...

进程地址空间(比特课总结)

一、进程地址空间 1. 环境变量 1 &#xff09;⽤户级环境变量与系统级环境变量 全局属性&#xff1a;环境变量具有全局属性&#xff0c;会被⼦进程继承。例如当bash启动⼦进程时&#xff0c;环 境变量会⾃动传递给⼦进程。 本地变量限制&#xff1a;本地变量只在当前进程(ba…...

Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?

Golang 面试经典题&#xff1a;map 的 key 可以是什么类型&#xff1f;哪些不可以&#xff1f; 在 Golang 的面试中&#xff0c;map 类型的使用是一个常见的考点&#xff0c;其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...

.Net框架,除了EF还有很多很多......

文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...

Go 语言接口详解

Go 语言接口详解 核心概念 接口定义 在 Go 语言中&#xff0c;接口是一种抽象类型&#xff0c;它定义了一组方法的集合&#xff1a; // 定义接口 type Shape interface {Area() float64Perimeter() float64 } 接口实现 Go 接口的实现是隐式的&#xff1a; // 矩形结构体…...

蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练

前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1)&#xff1a;从基础到实战的深度解析-CSDN博客&#xff0c;但实际面试中&#xff0c;企业更关注候选人对复杂场景的应对能力&#xff08;如多设备并发扫描、低功耗与高发现率的平衡&#xff09;和前沿技术的…...

python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)

更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...

从零实现STL哈希容器:unordered_map/unordered_set封装详解

本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说&#xff0c;直接开始吧&#xff01; 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...

基于TurtleBot3在Gazebo地图实现机器人远程控制

1. TurtleBot3环境配置 # 下载TurtleBot3核心包 mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src git clone -b noetic-devel https://github.com/ROBOTIS-GIT/turtlebot3.git git clone -b noetic https://github.com/ROBOTIS-GIT/turtlebot3_msgs.git git clone -b noetic-dev…...

现有的 Redis 分布式锁库(如 Redisson)提供了哪些便利?

现有的 Redis 分布式锁库&#xff08;如 Redisson&#xff09;相比于开发者自己基于 Redis 命令&#xff08;如 SETNX, EXPIRE, DEL&#xff09;手动实现分布式锁&#xff0c;提供了巨大的便利性和健壮性。主要体现在以下几个方面&#xff1a; 原子性保证 (Atomicity)&#xff…...