第二课: 理解Rust的所有权

Posted by JoshSu Blog on July 31, 2021

大家好, 欢迎大家来参加这次公开课, 今天跟大家一起探讨Rust的所有权机制, 所有权让Rust实现了既要保障内存安全又要无GC, 运行时高性能的目标, 所有权是Rust最大的卖点之一, 也是Rust连续六年成为最受欢迎的语言的原因.

你是否想学习Rust并且总是听到有关所有权(Ownership)和借用(Borrowing)的概念,但是你不能完全理解它到底是什么。所有权十分重要,理解这个概念对于初学Rust来讲是有很大好处的,并且这也能让你在实现程序的过程中避免很多编译错误.

今天给大家带来的主题是: 理解Rust的所有权, 我们将会更仔细地来看一看Rust是如何管理内存并且所有权为何极大地影响了我们在Rust中写代码的方式以及它是如何保证内存安全的.

PPT

首先我来简单的介绍一下自己.

我叫苏林, 是一名从事于互联网研发的程序员, 也是一名技术爱好者, 在互联网行业沉浮十余年, 先后效力于电商、SaaS领域, 对底层系统级开发比较感兴趣, 也才促使我学习和探索Rust语言.

PPT

我今天想给大家分享的内容一共包含四部分:

第一: 什么是内存安全?(What is Memory Safety anyway?) 在讨论是什么让Rust作为一门编程语言能够脱颖而出时,我们最好能够先来理解内存安全意味着什么?

第二: 堆和栈(Stack and Heap) 如果连这两种数据结构都不太熟悉, 去扯所有权, 我个人觉得简直就是在在扯淡.

第三: 理解所有权(Understanding Ownership) 所有权是Rust最大的卖点之一, 也是Rust连续六年成为最受欢迎的语言的原因.

第四: 移动和借用(Moves and Borrowing) Rust是怎么保证只有一个变量拥有它的值, 会进行更深入的讨论.

第五: 讨论Rustlings上move_semantics的5道题 通过这5道题加深对Rust所有权机制的理解.

题1:

把一个变量赋值给另一个变量会把所有权转移给受让者. 当变量v被move到v1时, 栈上的对象被逐位拷贝.

重定义(遮蔽)

Rust 的安全哲学要求变量默认是不可变的。

使用 mut 定义一个可变的变量.

题2:

当一个值被move的时候, Rust做一个浅拷贝; 创建一个深拷贝需要使用clone方法.

题3:

与 题1 类似

题4:

重构这段代码,使其不再有vec0并在fn main中创建向量,而是在fn fill_vec中创建,并将新鲜创建的向量从fill_vec转移到其调用者。

题5:

在同一个生命周期内,只能有一个可变引用和多个不可变引用.

这段代码试图对同一份数据创建两个可变引用. 如果我们想要编译这份代码, Rust会报出下面的错误.

虽然这看上去出乎意料, 但是却十分合理, Rust声称是内存安全的, 而不能对同一份数据进行多个可变引用便是保证内存安全的条件之一。如果在代码的不同地方存在着多个这样的可变引用, 就无法保证它们的其中之一不会以不可预期的方式修改数据.

另一方面, 同一份数据有多个共享引用也是有必要的.