【投稿】刀哥:Rust学习笔记 1
作者:刀哥
@[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的深入分析
- Python Garbage Collection 与 Objective-C ARCPython GC 与 Objective-C ARC
- SpringMVC DispatcherServlet执行流程及源码分析你要知道的SpringMVC DispatcherServlet执行流程及源码分析都在这里
- iOS runtime探究(三): 从runtime开始理解OC的属性property你要知道的runtime都在这里
- jQuery选择器大全(48个代码片段+21幅图演示)1
- KVC 使用方法详解及底层实现你要知道的KVC、KVO、Delegate、Notification都在这里
- jQuery选择器大全(48个代码片段+21幅图演示)2
- 神经网络-感知器
- NSNotificationCenter 通知的使用方法详解你要知道的KVC、KVO、Delegate、Notification都在这里
- Protocol与Delegate 使用方法详解你要知道的KVC、KVO、Delegate、Notification都在这里
- iOS多线程——你要知道的GCD都在这里你要知道的iOS多线程NSThread、GCD、NSOperation、RunLoop都在这里
- NSCopying和NSCoding对象序列化反序列化基础详解你要知道的NSCopying、NSCoding协议及对象序列化和反序列化都在这里
- KVO 正确使用姿势进阶及底层实现你要知道的KVC、KVO、Delegate、Notification都在这里
- iOS多线程——你要知道的NSOperation都在这里你要知道的iOS多线程NSThread、GCD、NSOperation、RunLoop都在这里
- iOS多线程——你要知道的NSThread都在这里你要知道的iOS多线程NSThread、GCD、NSOperation、RunLoop都在这里
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- linux防火墙iptables规则的查看、添加、删除和修改方法总结
- Linux expect实现自动登录脚本实例代码
- scRNA-seq marker identification(一)
- 关于linux权限s权限和t权限详解
- centOS7 桥接模式设置静态Ip的方法步骤
- linux环境下卸载oracle 11g的过程
- Seurat包基本分析实战—文献图表复现
- ubuntu配置tftp服务的步骤小结
- CentOS7下GitLab跨大版本升级的方法
- 解决Linux system v 共享内存问题
- Linux下core文件的使用方法详解
- 使用Kubeadm在CentOS7.2上部署Kubernetes集群的方法
- linux systemctl命令详解
- CentOS7使用dnf安装mysql的方法
- Linux中crontab定时任务不执行的原因