0%

2024春季开源操作系统训练营一阶段总结

Rust学习经验

作为经验分享,我不会写太多,一小篇足以

前言

Rust作为新时代的语言,其语法特性相对于以前的语言有着较大的差别,而且目前的Rust教程都是非常繁琐且没有梳理出一条很好的路线的,具体表现为既不是阶梯式也不是直接深入讲一个点,前后内容穿插令人无法理解。当然这也与Rust本身语言的特性相关,而并非完全是教程编写者的原因。

学习任何语言的思想都应该是读大量的项目源码,Rust也是如此,不过更应该先掌握Rust语法基础。

以下为Rust学习的部分参考资料:

官方学习文档

Rust圣经(可以看作官方文档的中文替代版)

THU-Rust学习建议

Rustlings

我的建议

先通过学习文档练习语法,然后刷Rustlings,学习过程中参考教程代码or别人的代码,通过crate doc文档查询相关crate源码

Rust特色分享

所有权与生命周期

众所周知,Rust同C++一样是没有GC的,虽然C++在C++11有过GC提案,但是并未有编译器实现(可以当作没有),在C++23移除。C++可以通过RAII控制资源,那么Rust也有智能指针可以实现RAII,但是本文不讨论这个。本篇的主角是所有权

既然我要聊所有权,那么我为什么要标注生命周期这个东西呢,那当然是因为所有权和生命周期息息相关,C++的内存安全问题基本上都是对于所有权和生命周期的错误使用导致的。而由于Rust中的所有权是在编译期进行的,对运行期的性能没有任何影响。

Rust的所有权有三个原则

  1. Rust 中每一个值都被一个变量所拥有,该变量被称为值的所有者
  2. 一个值同时只能被一个变量所拥有,或者说一个值只能拥有一个所有者
  3. 当所有者(变量)离开作用域范围时,这个值将被丢弃(drop)

下面将通过一段代码说明以上意思

1
2
3
4
5
6
7
8
9
10
fn main(){
let a = String::from("Hello Rust");
let b = a;//此时所有权转移到b
println!("{:?}", a); //Wrong !!!
let c = b.clone();//c通过克隆产生,不会拿走b所有权
{
let d = b;//d获得b的所有权,并在该代码段结束后drop
}
println!("{:?}", b); //Wrong !!!
}

当然这只是浅浅的一点例子,我无法在这说完,可以查看前言中的资料进行深入学习

生命周期

有一个关于很有意思的概念可以被应用于生命周期,我只会在此介绍这个概念。

三种映射

  1. 协变(covariant) T: R(T<’a>, T<’b>) = R(‘a, ‘b)。
  2. 逆变(contravariant) T: R(T<’a>, T<’b>) = ~R(‘a, ‘b),也就是若 ‘a<’b,则 T<’a> > T<’b>。
  3. 不变(invariant) T: R(T<’a>, T<’b>) = “<> 或 =”,也就是无法推导子类型关系

你会发现,看上面的概念是不是看不懂?

看不懂就对了,其实这个对于编程来说并没有什么卵用,只是一个很有意思的东西。

那么我们不从Rust的角度来看协变和逆变的概念。

A <: B 代表A是B的子类型
A -> B 以 A 为参数类型, 以 B 为返回值类型的函数类型
x : A 这里x是一个变量, 其类型为A

其实这里从继承关系来看就很好接受了,我们有三个类型如下:
A <: B <: C

这里A变成B、C是协变,B变成C是协变,C变成A、B是逆变,B变成A是逆变。

为什么呢?
定义如下:

协变(Covariance)是指子类向基类的转换.
逆变(Contravariance)是指基类向子类的转换.

是不是突然明白了

那这和生命周期有啥关系呢?

生命周期是有长短的,在哪开始在哪结束,那是不是就有变长变短,的概念了,协变和逆变的概念是不是就能套进去了?

1
2
3
4
5
6
7
8
9
10
fn main() {
let r; // ---------+-- 'a
// |
{ // |
let x = 5; // -+-- 'b |
r = &x; // | |
} // -+ |
// |
println!("r: {}", r); // |
} // ---------+

从上面可以看出显示看出r的生命周期和x的生命周期,那是不是生命周期变长的就是协变,生命周期变短的就是逆变了。

非常容易理解!

TODO!
PS:慢慢写