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

第19节 Node.js Express 框架

Express 是一个为Node.js设计的web开发框架&#xff0c;它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用&#xff0c;和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...

Linux 文件类型,目录与路径,文件与目录管理

文件类型 后面的字符表示文件类型标志 普通文件&#xff1a;-&#xff08;纯文本文件&#xff0c;二进制文件&#xff0c;数据格式文件&#xff09; 如文本文件、图片、程序文件等。 目录文件&#xff1a;d&#xff08;directory&#xff09; 用来存放其他文件或子目录。 设备…...

【Linux】shell脚本忽略错误继续执行

在 shell 脚本中&#xff0c;可以使用 set -e 命令来设置脚本在遇到错误时退出执行。如果你希望脚本忽略错误并继续执行&#xff0c;可以在脚本开头添加 set e 命令来取消该设置。 举例1 #!/bin/bash# 取消 set -e 的设置 set e# 执行命令&#xff0c;并忽略错误 rm somefile…...

逻辑回归:给不确定性划界的分类大师

想象你是一名医生。面对患者的检查报告&#xff08;肿瘤大小、血液指标&#xff09;&#xff0c;你需要做出一个**决定性判断**&#xff1a;恶性还是良性&#xff1f;这种“非黑即白”的抉择&#xff0c;正是**逻辑回归&#xff08;Logistic Regression&#xff09;** 的战场&a…...

【力扣数据库知识手册笔记】索引

索引 索引的优缺点 优点1. 通过创建唯一性索引&#xff0c;可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度&#xff08;创建索引的主要原因&#xff09;。3. 可以加速表和表之间的连接&#xff0c;实现数据的参考完整性。4. 可以在查询过程中&#xff0c;…...

家政维修平台实战20:权限设计

目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系&#xff0c;主要是分成几个表&#xff0c;用户表我们是记录用户的基础信息&#xff0c;包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题&#xff0c;不同的角色&#xf…...

uniapp中使用aixos 报错

问题&#xff1a; 在uniapp中使用aixos&#xff0c;运行后报如下错误&#xff1a; AxiosError: There is no suitable adapter to dispatch the request since : - adapter xhr is not supported by the environment - adapter http is not available in the build 解决方案&…...

ios苹果系统,js 滑动屏幕、锚定无效

现象&#xff1a;window.addEventListener监听touch无效&#xff0c;划不动屏幕&#xff0c;但是代码逻辑都有执行到。 scrollIntoView也无效。 原因&#xff1a;这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作&#xff0c;从而会影响…...

ABAP设计模式之---“简单设计原则(Simple Design)”

“Simple Design”&#xff08;简单设计&#xff09;是软件开发中的一个重要理念&#xff0c;倡导以最简单的方式实现软件功能&#xff0c;以确保代码清晰易懂、易维护&#xff0c;并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计&#xff0c;遵循“让事情保…...

安卓基础(aar)

重新设置java21的环境&#xff0c;临时设置 $env:JAVA_HOME "D:\Android Studio\jbr" 查看当前环境变量 JAVA_HOME 的值 echo $env:JAVA_HOME 构建ARR文件 ./gradlew :private-lib:assembleRelease 目录是这样的&#xff1a; MyApp/ ├── app/ …...