代码编织梦想


前言

   通过Rust程序设计-第二版笔记的形式对Rust相关重点知识进行汇总,读者通读此系列文章就可以轻松的把该语言基础捡起来。


1.所有权与移动

谈及内存管理,我们希望编程语言能具备两个特点:

  • 希望内存能在我们选定的时机及时释放,这使我们能控制程序的内存消耗;
  • 在对象被释放后,我们绝不希望继续使用指向它的指针,这是未定义行为,会导致崩溃和安全漏洞。

Rust 通过限制程序使用指针的方式出人意料地打破了这种困局。悬空指针、重复释放、使用未初始化的内存等。

Rust 程序中的缺陷不会导致一个线程破坏另一个线程的数据,进而在系统中的无关部分引入难以重现的故障。

相关问题:

看看所有权在概念层和实现层分别意味着什么?
如何在各种场景中跟踪所有权的变化?
哪些情况下要改变或打破其中的一些规则,以提供更大的灵活性?

1.1 所有权

拥有对象意味着可以决定何时释放此对象:当销毁拥有者时,它拥有的对象也会随之销毁。

变量拥有自己的值,当控制流离开声明变量的块时,变量就会被丢弃,因此它的值也会一起被丢弃。例如:

fn print_padovan() {
    let mut padovan = vec![1,1,1]; // 在此分配
    for i in 3..10 {
        let next = padovan[i-3] + padovan[i-2];
        padovan.push(next);
    }
    println!("P(1..10) = {:?}", padovan);
} // 在此丢弃

变量 padovan 的类型为 Vec<i32>。在内存中,padovan 的最终值如图所示。
在这里插入图片描述 跟C++ std::string 非常相似,不过缓冲区中的元素都是 32 位整数,而不是字符。

2.引用

3.特型与泛型

简介

本章展示特型的用法、工作原理,以及如何定义你自己的特型。

标准库提供的公共特型。之后的闭包、迭代器、输入 / 输出和并发。特型和泛型在所有这些主题中都扮演着核心角色。

Rust 通过两个相关联的特性来支持多态:特型和泛型。

特型是 Rust 体系中的接口或抽象基类。

为什么向类型添加特型不需要额外的内存?
如何在不需要虚方法调用开销的情况下使用特型?

泛型是 Rust 中多态的另一种形式。

泛型和特型紧密相关:泛型函数会在限界中使用特型来阐明它能针对哪些类型的参数进行调用。

3.1 使用特型

特型代表着一种能力,即一个类型能做什么。

  • 实现了 std::io::Write 的值能写出一些字节。
  • 实现了 std::iter::Iterator 的值能生成一系列值。
  • 实现了 std::clone::Clone 的值能在内存中克隆自身。
  • 实现了 std::fmt::Debug 的值能用带有 {:?} 格式说明符的 println!() 打印出来。

特型方法类似于虚方法。

3.2 特型对象

在 Rust 中使用特型编写多态代码有两种方法:特型对象和泛型。

在 Rust 中,引用是显式的:

let mut buf: Vec<u8> = vec![];
let writer: &mut dyn Write = &mut buf; // 正确

对特型类型(如 writer)的引用叫作特型对象。

特型对象的内存布局

在内存中,特型对象是一个胖指针,由指向值的指针和指向表示该值类型的虚表的指针组成。

C++ 也有这种运行期类型信息,叫作虚表或 vtable。

在这里插入图片描述在 C++ 中,虚表指针或 vptr 是作为结构体的一部分存储的,而 Rust 使用的是胖指针方案。结构体本身只包含自己的字段。这样一来,每个结构体就可以实现几十个特型而不必包含几十个 vptr 了。甚至连 i32 这样大小不足以容纳 vptr 的类型都可以实现特型。

3.3 泛型函数与类型参数

4.实用工具特型

5.闭包

fn sort_cities(cities: &mut Vec<City>) {
    cities.sort_by_key(|city| -city.population);
}

|city| -city.population 就是闭包。它会接受一个参数 city 并返回 -city.population。Rust 会从闭包的使用方式中推断出其参数类型和返回类型。

闭包相关问题:
Rust 的闭包与匿名函数有何不同?
如何将闭包与标准库方法一起使用?
闭包如何“捕获”其作用域内的变量?
如何编写自己的以闭包作为参数的函数和方法?
何存储闭包供以后用作回调?
Rust 闭包是如何实现的,以及它们为什么比你预想的要快?

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/yaoming168/article/details/136090310

蒲公英 · JELLY技术周刊 Vol.05: Rust & Electron 的高性能实践 -- Finda-爱代码爱编程

登高远眺 天高地迥,觉宇宙之无穷 基础技术 使用 JavaScript 框架的代价 作者从 JavaScript 下载时间、解析时间、执行时间、内存占用四个角度评测了 jQuery、Angular、React、Vue 四个框架,最终得出结论:「框架不值得」,应该选择原生 JavaScript 或选择超轻量级框架或在服务端渲染。此文可配

万字详文阐释程序员修炼之道-爱代码爱编程

作者:cheaterlin,腾讯 PCG 后台开发工程师 综述 我写过一篇《Code Review 我都 CR 些什么》,讲解了 Code Review 对团队有什么价值,我认为 CR 最重要的原则有哪些。最近我在团队工作中还发现了: 原则不清晰。对于代码架构的原则,编码的追求,我的骨干员工对它的认识也不是很全面。当前还是在 review

安卓动态链接库文件体积优化探索实践-爱代码爱编程

背景介绍 应用安装包的体积影响着用户下载量、安装时长、用户磁盘占用量等多个方面,据Google Play统计,应用体积每增加6MB,安装的转化率将下降1%。 安装包的体积受诸多方面影响,针对dex、资源文件、so文件

rust给py写拓展如此简单-爱代码爱编程

很久没写rust,主要是写业务逻辑实在用不上这高性能.不过惊奇发现rust和py结合的如此之好,记录下: 搞一个python环境,pip install maturin建立一个项目文件,cd进去 maturin init照

rust入门-爱代码爱编程

文章目录 一、HelloWorld二、控制台输入 以最简单的两个Rust程序例子入门Rust。首先需要下载安装Rust,之后在VSCode或Clion中运行Rust需要下载Rust插件 一、H

rust语言基础语法-爱代码爱编程

文章目录 一、让程序跑起来二、常量和变量1.常量2.变量 三、数据类型四、条件判断1.if语句2.match语句 五、循环语句1.loop 无条件循环2.while 条件循环3.for 集合遍历

rust的多线程编程:创建与管理线程及同步机制解析-爱代码爱编程

一、创建线程的方法 在Rust中,使用std::thread模块来创建和管理线程。创建新线程的基本方法是调用thread::spawn函数,该函数接受一个闭包作为参数,并在新的线程中执行这个闭包。为了确保线程安全,如果闭包需要访问主线程的数据,则必须通过move语义转移数据的所有权。以下是一个简单的示例: use std::thread; fn ma

从零开始:用 rust 编写你的第一个 web 服务-爱代码爱编程

Rust 是一种现代、高性能的编程语言,近年来在 Web 开发领域也有了一席之地。本文将介绍如何使用 Rust 编写一个简单的 Web 程序,从搭建开发环境到创建第一个 Web 页面。 1. 开发环境搭建 首先

rust方法自动解引用测试,总结和补充-爱代码爱编程

// 定义一个结构体MyBox,包含一个原始指针 struct MyBox<T>(T); // 方法调用 . 操作,对方法的self 进行加& &mut * 还有 无大小转换 trait MyTrait { fn test0(mut self, x: &i32) where Self: Sized {

linux赋予普通用户权限-爱代码爱编程

当我们在Linux系统中操作文件或目录时,有时候会遇到权限的问题。为了正确管理文件和目录的所有权,我们可以使用sudo chown命令。在本文中,我将介绍这个命令以及它的一个示例用法。 什么是sudo chown命令?

rust基础拾遗-爱代码爱编程

Rust基础拾遗 前言1.导览2. 环境配置(rustup 与 Cargo)3. Rust 函数4. 处理命令行参数5. 搭建 Web 服务器6. 并发6.1 从像素到复数的映射6.2 绘制曼德博集6.3 写入