the-rust-programming-language学习记录

Go!Go!Go!

最早听闻rust应该还是刚学go的时候,但因为go属于是c语言族里里面的一员真的很喜欢,并且同样出自k神之手,所以当时没有太多犹豫就all in go了,go不仅和c流派很好的保持了一致,还极大提升了开发效率,说是c的迭代版完全没有问题。但之前有一次对于go项目的性能调优,也花了比较久的时间调研和了解了gc,当时go应该还是用的三色标记法,对于内存的释放是通过染色然后不停地扫描逐步释放的,会有STW的问题,同时本身扫描肯定也会有性能消耗,所以目前所有带gc功能的编程语言,不管是Go还是Java其实都是有性能上限的,所以从那个时候我心理就一直有个问号,这样真的好么,会不会有更好地解决方法呢?

Rust的所有权

上面的问题,很长一段时间都在思考,也不是说专门花时间去想,而是平时写go的时候就时不时的想一下,比如我在这里创建了一个变量,其实malloc了内存对吧,那么后续他会被gc给释放掉,这个过程就好比是我用了什么工具,然后就扔到了桌子上不管啦,等过了一段时间老妈打扫屋子发现了,就把这个工具又收拾到了工具箱了,这就跟我们使用gc一样,我们写了一堆代码然后从不收拾,把这些都丢给了gc,虽然心智负担确实降低了很多,但这些问题都堆积到了gc那里,把问题后移了,并且因为我们并没有告诉gc我这个变量什么时候不用了,只能依靠gc不停地扫描来进行释放,这个其实从某种程度上来说真的很浪费,就在这时脑海里突然想到了rust的所有权这个概念,感觉和这个想法很接近,于是拿出了rust的书开始看了起来。

看到所有权的时候,豁然开朗!这不就是刚才想的一回事么!我们和编译器分工协作,我来做我擅长的事情,比如逻辑的梳理以及变量的作用生效范围的标示!然后编译器来做他擅长的东西,比如语法检查,以及根据我做的标示来做内存的申请和释放!我们各司其职,把各自擅长的工作做好,这样我得心智负担虽然相对gc语言有所上升但代码的性能也是增长显著!并且我个人认为,作为开发者如果能对内存管理做好管理不仅可以提升性能,同时也能降低内存错误引发的安全问题,这个其实也算是分内之事。

Rust的其他特性

rust的错误处理也很有意思,在go里面return的时候把error一起返回出去(这个被很多人吐槽,语法很长,没有java的异常处理),rust这里是有option类型,他在执行正确的时候可以是想要的struct,在执行错误的时候是一个error类型,也很有意思。

rust锁的处理和go有一些相似,在go里面我们往往使用defer在函数返回的时候进行锁的释放,在rust当中这里有一些类似但也有不同,rust是在执行完函数的作用域的时候会把相关资源进行释放和清空,所以在锁这块也是如此,我们在调用了lock之后是不需要再调用unlock的,在这个锁的作用域执行完之后会自动进行锁的释放,例如以下代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
use std::sync::{Arc, Mutex};
use std::thread;

fn main() {
let counter = Arc::new(Mutex::new(0));
let mut handles = vec![];

for _ in 0..10 {
let counter = Arc::clone(&counter);
let handle = thread::spawn(move || {
let mut num = counter.lock().unwrap();
*num += 1;
});
handles.push(handle);
}

for handle in handles {
handle.join().unwrap();
}

println!("Result: {}", *counter.lock().unwrap());
}

一些想法

rust真的是非常现代的语言,虽然相对其他语言来说很年轻但也吸收了其他语言很多的优点,甚至于在编译错的时候会把相关建议和标准给出来(虽然编译速度也被很多人吐槽),但我个人真的还是非常喜欢rust的,在我看来rust和go没有谁更好更坏,而是他们各自很好的聚焦各自的领域来解决相应领域的问题,以上总结只是rust的冰山一角,其他的放在以后复习的时候再继续更新~

转载请注明来源链接 http://just4fun.im/2022/08/01/the-rust-programming-language/ 尊重知识,谢谢:)