rust程序设计语言 介绍了关于rust的方方面面, 我跟着学了两遍,中间隔了差不多一年,每次都是从零开始入门, 最近两个月用rust实际开发了个应用,才算真的入门. 这里记录下使用中的一些体验.
1 关于rust本身
数据类型,流程控制都很基本,crate和包封装也是基础.
1.1 所有权
所有权很重要, 开发中经常碰到的就是所有权问题, 特别是用到异步和多线程的时候; 当然这也是rust保证程序正确的一个很重要的手段, 一开始不太适应, 要逼着自己思考和组织数据, 熟悉了之后就好了.另外所有权问题涉及到切片Slice, 主要用在传参和字符串, 需要掌握和熟练使用.
1.2 枚举
rust的枚举相比c++有个很大的特点是可以包含更多内容, 方便组织数据. Option和Result是rust中广泛使用的枚举类型. 枚举常常和模式匹配配合使用, 使rust的程序逻辑在编译阶段就尽量保证穷举所有情况.
1.3 字符串
要记得rust的字符串是用utf8存储的, 要区分开String, &str, [u8] 这些数据类型.
1.4 错误处理
很重要, 如果没有特别的需求,可以不用自己定义错误类型, 但经常要在函数调用的时候传递错误, 建议了解和使用anyhow这个crate,方便错误传递.如果要自己定义,建议使用thiserror.
1.5 泛型,trait
泛型要了解, 重要的是trait, 有时候这两个会弄混–学的时候不会,用的时候就模糊了. 泛型是编译时分发, trait算是动态分发.另外用到第三方库的时候, 也有很多接口是用trait给出的, 看接口文档的时候要记得看看实现了哪些trait.
1.6 生命周期
第一个应用程序可以不用自己写生命周期, 完全依赖复制和借用就行. 但也要了解一下.
1.7 迭代器和闭包
迭代器很多方法定义在Iterator这个trait中, 建议浏览一遍,很多有用的. 闭包要掌握, 很多地方都会用到.
1.8 多线程和异步
我是直接用了tokio, 会同时涉及到多线程和异步, 实现异步运行时依赖的async/await,Future,Waker这些可以先不管, 先了解tokio几个基本概念和select的用法, 多运行多调试多重构, 这是个麻烦的过程,但是必经之路.
2 第三方库
lib.rs是第三方库集合,但这里很多,有时候也不知道到底要找哪个. 这里列一下用到的一些第三方库.
2.1 tokio
rust的异步运行时. rust语言本身只提供了async/await支持, 标准库提供了Future用于实现运行时的统一接口, tokio则提供了异步运行时本身和最终的用户接口. 网络程序的话,建议直接学tokio, 绕不开的.
里边很重要的是tokio::sync::Mutex和std::sync::Mutex的区别, tokio::sync::{mpsc, oneshot, broadcast}几个通道的使用, select的使用(这个相当重要).
2.2 clap
命令行解析库.
2.3 tracing
配合tokio的日志库. clia-tracing-config是个方便的工具库, 用于方便初始化tracing日志库.
2.4 serde, toml, serde_json
serde是序列化接口, toml用于解析配置文件, serde_json用于json操作.
2.5 rdkafka
kafka的rust接口.
2.6 prost, prost-build
protobuf的rust接口. prost-build用于在编译之前从.proto文件生成.rs数据接口.
2.7 bytes
方便操作二进制数据的库, 最开始用过deku, 但deku的问题是还不够灵活,特别是处理字段间关联会很麻烦. 还不如自己用bytes直接操作这段内存.
2.8 hex
主要用于打印二进制数据, hex::encode() 将字节编码成十六进制字符串, hex::decode()从十六进制字符串解码出原始字节.
2.9 chrono
方便的 时间格式化工具.
2.10 sqlx
支持mysql, sqlite, postgres连接池, 支持tokio异步.
2.11 redis
支持redis异步.
2.12 axum
方便集成web api, 支持异步.
2.13 scopeguard
提供defer!, 用于异步时的范围资源清理.
2.14 anyhow, thiserror
前者用于错误传递,后者用于自定义错误.
2.15 criterion
替换cargo提供的性能测试框架.
3 总结
rust在保证大部分场景是安全高效的情况下,会把一些怪异的情况堆积到角落,比如Pin, unsafe这些, 进而出现很复杂的语法,才能安抚编译器, 但对我的第一个应用来说, 没有(直接)使用这些东西也完成正常功能了.
用完rust,最大的感觉是安心, 很少运行时错误,大部分在编译阶段就被发现,或者被语言本身的机制所规避. 单元测试框架也很方便, 重构后也比c++更有信心, 总之心智负担小, 算是快爬到**”愚昧之巅”**了.