作者:刀哥
@[TOC](Rust 学习心得<1>:开篇)
近段时间在学习研究Rust
。都说Rust
学习曲线陡峭,感觉果然如此。之前学习Go
,基本上没有专门去看语法,只是在需要的时候上网查一查,再花点时间看看大型的开源软件项目,差不多就可以写生产级别的代码了。而Rust
则不然,至少本人花了差不多两三周的时间专门学习语法,然而去看开源的项目依然觉得很吃力,又花了一些时间才搞明白了Rust
的几种编码模式,特别是异步模式,又分为poll
循环的方式、combinator
方式和.await
协程的方式,各种坑比较多,填坑的过程还是比较费劲的。
整个大约两个多月学习过程中,曾经碰到过很多的问题,在网上阅读过很多的文章寻找答案,也和有经验的开发者进行过微信交流,总体感觉Rust
还是一个正在发展中的语言,不同版本之间有一些差异,特别是Rust
并没有提供一个非常完整runtime
(也可以理解成是开放的,提供了各种选项),异步编程模式还有tokio
和async-std
这样的阵营分裂,网上相关的资料也是鱼龙混杂,对于初学者而言,有可能迷失在一些错误的描述或者相互矛盾的各种资料中,走一段冤枉路。故而,在这里用文字将自己的学习历程和心得体会整理出来,希望能够对他人有所帮助。
语法
相对而言,Rust
的语法是挺特别的。因为有生存周期和借用检查这类独有的概念,所以语法上看上去比较复杂。作为一种现代编程语言,大量使用了泛型,但是也带来代码可读性较差的问题。相信所有的初学者都会对层层包裹的泛型参数及其限定感到头痛,可能需要花费一段时间来适应一下。而枚举类型Option<T>
替代Null
,错误处理Result<T,E>
也是有特色的地方,然也导致相关的代码略显臃肿(个人体会,完成相同功能,Rust
代码篇幅总是较之Go
代码明显更长)。总之,学习Rust
,语法是第一道门槛,需要一点耐心和韧性。
“安全”和“高性能”
所有权概念解决内存安全和GC
的问题,是Rust
语言的基石,也是整个系统的亮点。结合Type系统和Trait限定(Send, Sync),Rust
用一种不那么直观但极为优雅的方式规定了多线程编码的基本要素。也就是说,除非写Unsafe
,否则程序员无法制造出C/C++
中常见的内存double free问题,也没机会写出线程不安全的代码,这类问题在大型软件项目后期基本都是灾难。然而,Rust
并不能解决代码的逻辑错误。我们一样会碰到内存泄漏,多线程死锁之类的问题。一般看来,多线程死锁差不多也是灾难级别的问题。此外,关于高性能,很多时候是Unsafe
的同义词,而使用Unsafe
,Rust
就退化为C
语言。因此,对于Rust
“安全”和“高性能”,需要有一个辩证的认识。
同步,异步
Rust
提供开放的选项,怎么写代码是程序员的选择。同步的代码比较直接,掌握了Rust
语法就可以看懂,容易上手。当然,如果仅仅是同步模式多线程的代码,Rust
差不多相当于一个增强版的C++
。同步模式的代码与异步模式代码的观感上差别很大。或者说,没有专门学习过异步编程模式,很可能完全看不懂异步的代码。异步模式对于重视I/O
吞吐的应用场景意义重大,主流编程语言纷纷加入了异步模式的支持,特别是Go
原生支持且只支持异步模式。然而,Rust
异步编程模式需要学习除语法之外的更多内容,多了不少新的概念,还有不同风格写法,掌握起来有一定难度。类库还有诸如 tokio 与 async-std 的不同阵营,无疑很大程度地又增加了学习的难度。而无论 tokio 或是 async-std,成熟度都有欠缺,远远不如Go
简单易用。但是对于使用异步编程模式的开发人员,还是很有必要了解异步模式的工作原理和技术实现,否则,面对一些相对复杂的问题可能就束手无策了。
第三方类库
Rust
因为其高门槛,注定就是小众的。目前来看,第三方类库能够提供的轮子数量有限,质量堪忧,与同样号称系统编程语言的Go
差距巨大,在劳动生产率上无法相提并论。如果从头开始一个大型项目,是否选用Rust
,取舍值得三思。究竟需要“安全”和“高性能”,还是快速开发,尽早交付?
开发工具
这一点需要用力吐槽。相较于使用Goland
进行Go
开发的轻松愉悦,使用Clion
进行Rust
开发可谓惨不忍睹。编辑器无法很好地理解或展开Rust
宏,因此语法提示等功能都会失效,有点盲人摸象的感觉。调试器断点不可靠,很多时候被迫祭出printf
大法,调用栈很难提供有用的信息,被层层包裹的变量无法查看,等等。如果说Goland
可以打9分,那么Clion
只能是不及格。另外,曾经尝试过VSCode
,感觉还不如Clion
。展望未来,随着Rust
被更多认可并得到更多支持,开发工具的改善和提高是可以预期的,特别是调试器,针对Rust
做相关的优化后相信体验会大幅改善。然而,因为Rust
语法的复杂性以及大量依赖泛型的特性,冀望Rust
开发工具的体验效果达到Go
开发工具的程度,估计不大现实。
网上各种资料
相较于广泛流行的Java
,Go
等语言,Rust
的生态不可同日而语,相关资料、文献不够丰富。特别缺乏高质量的中文原创内容。不少的翻译文章,原文内容丰富,质量很高,但译者可能并没有完全理解原文的精髓,很多地方直译了事,没能讲到点子上。这时候,建议读者找到原文对比阅读。几位Rust
核心开发人员的博客,建议关注。
Rust 相关的文章或教程推荐
入门教程:
- Book:经典入门教程。个人觉得过于简练,略过了很多内容
- 深入浅出
Rust
:中文书籍,作为语法学习很不错。内容详尽,个别地方稍显陈旧
异步编程:
- The Future With Futures:文章有点久远,但还是值得一读
- Asynchronous Programming in Rust:tokio 团队关于异步编程的教程,系统性地讲解了异步编程的来龙去脉
- Async programming in Rust with async-std:async-std 团队关于异步编程的教程。里面有一个非常棒的设计实现聊天程序的教程案例。这不是一个简单的示例,至少不是用unwrap来写的简单示例...
博客:
- withoutboats' Blog :著名的withoutboats,博客中有非常多内容,方方面面
- stjepang's Blog:crossbeam,smol 的作者。smol 现在是 async-std 的底层支撑。作者博客中详尽地介绍了 executor 的实现细节-
- snoyman's Blog: 讲解了async fn 的原理,值得一读。博客中有一系列关于
Rust
的精彩文章
中文:
- 最近学写 async/await 被 Rust 毒打的经验:这篇文章作者写得非常生动具体,里面提到的问题都是亲身体会
- Rust Async: 深度分析AtomicWaker:关于waker的深入分析
评论区
写评论目测是一套好的笔记 加油
Asynchronous Programming in Rust 是Rust官方写的,跟tokio什么关系。。。 另外go没范型,错误处理全靠if err!=nil,怎么写起来相比Rust,代码还更短。。。