Rust 进阶教程

Rust 进阶教程

在基础教程中,我们已经了解了Rust的基本语法和核心概念。本文将进一步探讨Rust的进阶特性和应用,包括泛型、闭包、迭代器、异步编程、宏和unsafe代码等。

目录

  1. 泛型
  2. 闭包和迭代器
    • 闭包
    • 迭代器
  3. 异步编程
  4. Unsafe代码
  5. FFI(外部函数接口)
  6. 设计模式
  7. 性能优化
  8. 案例分析

泛型

泛型允许我们编写更通用和复用的代码。Rust中的泛型主要用于函数、结构体、枚举和方法。

泛型函数

fn largest<T: PartialOrd>(list: &[T]) -> &T {let mut largest = &list[0];for item in list.iter() {if item > largest {largest = item;}}largest
}fn main() {let number_list = vec![34, 50, 25, 100, 65];let result = largest(&number_list);println!("The largest number is {}", result);let char_list = vec!['y', 'm', 'a', 'q'];let result = largest(&char_list);println!("The largest char is {}", result);
}

泛型结构体

struct Point<T> {x: T,y: T,
}impl<T> Point<T> {fn new(x: T, y: T) -> Self {Self { x, y }}
}fn main() {let integer_point = Point::new(5, 10);let float_point = Point::new(1.0, 4.0);println!("Integer Point: ({}, {})", integer_point.x, integer_point.y);println!("Float Point: ({}, {})", float_point.x, float_point.y);
}

闭包和迭代器

闭包

闭包是可以捕获其环境的匿名函数。Rust中的闭包可以存储在变量中,作为参数传递给函数等。

fn main() {let add_one = |x: i32| -> i32 { x + 1 };let result = add_one(5);println!("Result: {}", result);let mut x = 5;let mut add_to_x = |y: i32| {x += y;};add_to_x(10);println!("x: {}", x);
}

迭代器

迭代器用于在集合上进行迭代操作。Rust中的迭代器具有惰性,即只有在需要时才会执行。

fn main() {let v1 = vec![1, 2, 3];let v1_iter = v1.iter();for val in v1_iter {println!("Got: {}", val);}let v2: Vec<i32> = v1.iter().map(|x| x + 1).collect();println!("Transformed vector: {:?}", v2);
}

异步编程

Rust通过async和await关键字支持异步编程,使得编写并发代码变得更加容易。

use tokio::time::{sleep, Duration};async fn do_something() {println!("Doing something...");sleep(Duration::from_secs(2)).await;println!("Done!");
}#[tokio::main]
async fn main() {let future1 = do_something();let future2 = do_something();tokio::join!(future1, future2);
}

宏是用于生成代码的强大工具。Rust有两种主要的宏:声明宏(macro_rules!)和过程宏。

声明宏

macro_rules! say_hello {() => {println!("Hello!");};
}fn main() {say_hello!();
}

过程宏

过程宏通常用于自定义属性和派生。

use proc_macro::TokenStream;#[proc_macro]
pub fn my_macro(input: TokenStream) -> TokenStream {let input_str = input.to_string();format!("fn generated_fn() {{ println!(\"{}\"); }}", input_str).parse().unwrap()
}

Unsafe代码

Rust默认是安全的,但有时需要进行低级操作,这时可以使用unsafe代码块。

fn main() {let mut num = 5;let r1 = &num as *const i32;let r2 = &mut num as *mut i32;unsafe {println!("r1: {}", *r1);println!("r2: {}", *r2);}
}

FFI(外部函数接口)

Rust可以与其他语言(如C)进行互操作,这通常通过FFI实现。

调用C代码

extern "C" {fn abs(input: i32) -> i32;
}fn main() {unsafe {println!("Absolute value of -3 according to C: {}", abs(-3));}
}

设计模式

Rust也支持常见的设计模式,如单例模式、观察者模式等。

单例模式

use std::sync::{Arc, Mutex};
use std::thread;struct Singleton {value: i32,
}impl Singleton {fn instance() -> Arc<Mutex<Self>> {static mut SINGLETON: Option<Arc<Mutex<Singleton>>> = None;unsafe {SINGLETON.get_or_insert_with(|| {Arc::new(Mutex::new(Singleton { value: 0 }))}).clone()}}
}fn main() {let singleton = Singleton::instance();{let mut singleton = singleton.lock().unwrap();singleton.value = 42;}let singleton = Singleton::instance();println!("Singleton value: {}", singleton.lock().unwrap().value);
}

性能优化

Rust的性能优化包括使用内联、减少内存分配和使用高效的数据结构等。

内联函数

#[inline]
fn add(x: i32, y: i32) -> i32 {x + y
}fn main() {let result = add(5, 10);println!("Result: {}", result);
}

使用高效的数据结构

use std::collections::HashMap;fn main() {let mut map = HashMap::new();map.insert("key1", 10);map.insert("key2", 20);println!("Value for 'key1': {}", map.get("key1").unwrap());
}

案例分析

通过一个简单的Web服务器项目来综合应用所学知识。

项目结构

simple_web_server
├── Cargo.toml
└── src├── main.rs└── lib.rs

代码实现

Cargo.toml
[package]
name = "simple_web_server"
version = "0.1.0"
edition = "2018"[dependencies]
tokio = { version = "1", features = ["full"] }
hyper = "0.14"
src/lib.rs
use hyper::service::{make_service_fn, service_fn};
use hyper::{Body, Request, Response, Server};
use std::convert::Infallible;
use std::net::SocketAddr;async fn handle_request(_req: Request<Body>) -> Result<Response<Body>, Infallible> {Ok(Response::new(Body::from("Hello, World!")))
}pub async fn run() {let addr = SocketAddr::from(([127, 0, 0, 1], 8080));let make_svc = make_service_fn(|_conn| {async { Ok::<_, Infallible>(service_fn(handle_request)) }});let server = Server::bind(&addr).serve(make_svc);if let Err(e) = server.await {eprintln!("Server error: {}", e);}
}
src/main.rs
#[tokio::main]
async fn main() {simple_web_server::run().await;
}

运行项目

cargo run

访问 http://127.0.0.1:8080,您将看到“Hello, World!”的响应。

以上就是Rust的进阶教程,通过学习这些内容,您将能够更好地掌握Rust并开发出更复杂和高效的应用程序。

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

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

相关文章

pdf怎么拆分成一页一页?4种拆分方法分享

在日常的办公学习中&#xff0c;PDF文档因其跨平台、易阅读、不易篡改等特性&#xff0c;成为我们工作和学习中不可或缺的一部分。然而&#xff0c;当我们需要对PDF进行编辑、打印或分享时&#xff0c;有时需要将整个PDF文档拆分成一页一页的单独文件。那么&#xff0c;如何高效…

深入理解Vue生命周期钩子函数

深入理解Vue生命周期钩子函数 Vue.js 是一款流行的前端框架&#xff0c;通过其强大的响应式数据绑定和组件化的开发方式&#xff0c;使得前端开发变得更加简单和高效。在Vue应用中&#xff0c;每个组件都有其生命周期&#xff0c;这些生命周期钩子函数允许开发者在不同阶段执行…

2024 AIGC 技术创新应用研讨会暨数字造型设计师高级研修班通知

尊敬的老师、领导您好! 为深入响应国家关于教育综合改革的战略部署&#xff0c;深化职业教育、高等教育改革&#xff0c;发挥企业主体重要作用&#xff0c;促进人才培养供给侧和产业需求侧结构要素全方位融合&#xff0c;充分把握人工智能创意式生成(AIGC)技术在教育领域的发展…

【ruoyi】docker 项目实战

一、引言 介绍ruoyi(若依)框架 本项目使用若依前后台分离框架 https://gitee.com/ranmaxli/basic-business-platform 解释为什么选择Docker进行项目开发 使用docker是因为方便数据迁移、部署、管理 二、Docker基础知识 Docker基本概念 容器与虚拟机

初学Spring之 IOC 控制反转

Spring 是一个轻量级的控制反转&#xff08;IOC&#xff09;和面向切面编程&#xff08;AOP&#xff09;的框架 导入 jar 包&#xff1a;spring-webmvc、spring-jdbc <dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc&l…

HTTPS数字证书验证论述

1 概述 网络请求方式通常分为两种&#xff0c;分别是HTTP请求和HTTPS请求&#xff0c;其中HTTP的传输属于明文传输&#xff0c;在传输的过程中容易被人截取并且偷窥其中的内容&#xff0c;而HTTPS是一种在HTTP的基础上加了SSL/TLS层&#xff08;安全套接层&#xff09;的安全的…

解决expand-change第一次展开无数据显示与实现

最近写需求时用到了expand-change表格展开回调&#xff0c;但我发现第一次展开后并没有展示任何数据&#xff0c;但我的返回值是存在的&#xff0c;当第二次展开时发现数据就有了。此原因是因为获取数据的接口是异步的&#xff0c;导致Dom渲染不同步导致的&#xff0c;其实解决…

Ubuntu24.04 Isaacgym的安装

教程1 教程2 教程3 1.下载压缩包 link 2. 解压 tar -xvf IsaacGym_Preview_4_Package.tar.gz核心教程在 isaacgym/docs/install.html下 3. 从源码安装 Ubuntu24.04还需首先进入虚拟环境 python -m venv myenv # 创建虚拟环境&#xff0c;已有可跳过 source myenv/bin/a…

Redis持久化详解

【关闭文件、AOF 刷盘、释放内存这三个任务都有各自的任务队列】所以不是单线程 Redis有两种持久化方案&#xff1a; RDB持久化 AOF持久化 基于Redis集群解决单机Redis存在的问题 【Redis是单进程的】 【也有人做分布式section】 【主从集群中多个从就是做负载均衡的】 …

如何在Java中实现函数式编程

如何在Java中实现函数式编程 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01; 在Java中&#xff0c;函数式编程是一种编程范式&#xff0c;它将计算视为数学函数…

在Linux系统中查找并计数正在运行的ffmpeg进程数量

ps aux | grep "ffmpeg" | grep -v "grep" | wc -l 这条命令是一个组合命令&#xff0c;用于在Linux系统中查找并计数正在运行的ffmpeg进程数量&#xff0c;同时排除了搜索命令本身&#xff08;即grep "ffmpeg"&#xff09;的干扰。下面是对每个…

Java识别图片中的二维码

引入依赖 <dependency><groupId>org.bytedeco</groupId><artifactId>javacv</artifactId><version>1.5.10</version> </dependency><dependency><groupId>org.bytedeco</groupId><artifactId>javacp…

while陈述

回圈是用来进行进行重复性的工作&#xff0c;典型的回圈会进行下列三项基本任务 1. 控制变数初始设定2. 回圈结束条件测试3. 调整控制变数的值 关键字 while构成C 中回圈的一种&#xff0c;常用于没有确定重复次数的回圈&#xff0c;同时while后面接着小括弧为回圈结束的条件…

上位机第二弹

之前写的代码用上了 现在想想 &#xff0c;北向一侧还挺难搞&#xff0c;设计很巧妙

Continual Test-Time Domain Adaptation--论文笔记

论文笔记 资料 1.代码地址 https://github.com/qinenergy/cotta 2.论文地址 https://arxiv.org/abs/2203.13591 3.数据集地址 论文摘要的翻译 TTA的目的是在不使用任何源数据的情况下&#xff0c;将源预先训练的模型适应到目标域。现有的工作主要考虑目标域是静态的情况…

python - 列表 / 元组 / 字符串

一.列表 由于pyhon的变量没有数据类型&#xff0c;所以python是没有数组的&#xff08;因为数组只能存放一种类型&#xff0c;要么全部存放整型&#xff0c;要么全部存放浮点型&#xff09;&#xff0c;只有列表list&#xff0c;所以整数&#xff0c;浮点数&#xff0c;字符串…

传输线阻抗匹配电阻端接的方式

电路为什么需要端接&#xff1f; 众所周知&#xff0c;电路中如果阻抗不连续&#xff0c;就会造成信号的反射&#xff0c;引起上冲下冲、振铃等信号失真&#xff0c;严重影响信号质量。所以在进行电路设计的时候阻抗匹配是很重要的考虑因素。 对我们的PCB走线进行阻抗控制已经…

双指针系列第 8 篇:盛水最多的容器。几句话讲明白!

Leetcode 题目链接 思路 取首尾双指针和水量如下所示&#xff0c;设高度函数为 h ( i ) h(i) h(i)&#xff0c;在下图中 h ( l ) < h ( r ) h(l) < h(r) h(l)<h(r)。 观察以 l l l 为左边界所能构成的其他水量&#xff0c;与矮的右边界搭配结果如下。 与高的…

jdk17卸载后换jdk1.8遇到的问题

过程&#xff1a; 1、找到jdk17所在文件夹&#xff0c;将文件夹进行删除。&#xff08;问题就源于此&#xff0c;因为没删干净&#xff09; 2、正常下载jdk1.8&#xff0c;按照网上步骤配置环境变量&#xff0c;这里我参考的文章是&#xff1a; http://t.csdnimg.cn/Svblk …

【RT摩拳擦掌】如何构建RT AVB switchendpoint平台

【RT摩拳擦掌】如何构建RT AVB switch&endpoint平台 一&#xff0c;文档简介二&#xff0c;平台构建2.1 软硬件情况2.2 配置RT1170 AVB端点2.2.1 1块MIMXRT1170开发板做talker配置2.2.2 2块MIMXRT1170开发板做listener配置 2.3 AVB Switch 配置2.3.1 MOTU AVB Switch2.3.2 …