浅分享下个人喜欢 Rust 超过其他语言的原因

34 天前
 ciaoSora

本人技术实力一般,所以自认为更能从大众程序员的视角对比一下 Rust 和其他语言,以及浅浅聊下为什么更喜欢 Rust 。

用过很多语言了,包括 C, C++, Go, JS, TS, C#。最近几个月一直在用 Rust 工作,用下来的整体体验就是:其他语言用着不爽的地方,在 Rust 这边总是能非常自然地解决。以下是详细版。

内存管理

大家用 Rust 基本都是奔着这个来的,这方面确实是吊打 C/C++。C++ 的智能指针是在运行时保证安全的,跟 Rust 在编译期保证安全没法比。而且,在 Rust 里也可以用 unsafe 来手动管理内存,非常灵活。跟其他带 GC 的语言比就见仁见智了。

工具链

配套工具可以说是一应俱全,都是由官方提供,令我这种想开箱即用的程序员体验非常好。包管理器有 Cargo ,代码格式化工具有 rustfmt ,linter 有 clippy ,还有 VSCode 插件。C/C++ 就不说了,非常难评。Go 的工具链也不错,包管理、格式化工具之类的也都有(但是不能不吐槽早年间的奇葩设计 GOPATH),感觉能打个平手。JS/TS 生态感觉会有些混乱,包管理器就有好几个了,然后 linter 不自带,虽然配置好了之后用起来也很舒服,但是自己配置会有些烦,不像 Rust 开箱即用。C# 就更复杂了,不过考虑到这是微软那一套东西,似乎就该是臃肿又难用。

错误处理

Rust 采用返回 Result<T, E> 的方式,Go 采用返回多个值(其中有一个表示是否有错),其他都是 throw-try-catch 。

个人很不喜欢 throw-try-catch 的方式,首先 try block 自己是一个 scope ,我不得不在 try block 的外面先声明变量,然后再在 try block 里给变量初始化/赋值,很不喜欢这样子。其次就是,比如 JS/TS ,就不会强制要求定义函数时要同时定义该函数可能抛出的异常的类型,这就让我开发时感觉如履薄冰,我永远不知道会有什么神奇的异常被抛出。

Go 的 if err != nil 已经被很多人诟病过了,虽然我认为这样子做已经比 throw-try-catch 好一些了——因为强制程序员错误处理或者显式表明不想处理——但是在函数的返回值里,当出错时,表示错误的返回值有意义而其他返回值无意义;当顺利执行时,表示错误的返回值无意义而其他值有意义,这个设计对我来说实在是槽点太大了。

Rust 则让函数返回一个 Result<T, E> 的 enum value ,这就非常优雅,一个返回值承载了顺利和出错这两种情况,而且跟 Go 一样,这强制程序员处理错误或者显示表明不想处理。除此以外,假设函数 fun1 调用了 fun2fun1 的返回值类型为 Result<T1, E1>fun2 的返回值类型为 Result<T2, E2>, 当 E2 类型能「转换」(Into trait )成 E1 类型或者 E2E1 相同时,若 fun1 想要直接返回 fun2 返回的错误时,有语法糖,使得代码可读性提高很多。

元编程

Rust 支持简单的用 macro_rules! 定义的宏,更复杂的宏(过程宏,procedural macro )可以用标准 Rust 语言实现,只需要写一个接收 token 输入,并且输出 token 的函数即可。这些宏在编译期间会被编译器执行并展开,然后再进行后续编译。

C/C++ 的宏只支持字符串处理,与 Rust 能在 token 级别处理形成鲜明对比。C++ 还支持 template ,不过这方面 Rust 更加强大(配合上 Rust 的强大的宏)。

TS 的 decorator 确实也算元编程,但是 decorator 的内容是在运行时执行的,损失了一点点运行效率。C# 印象中也是运行时(错了的话麻烦纠正我,谢谢)。

(不过 TS 的编译器类型推断确实很骚,能在编译时期用函数式编程的方法做归并排序…… 虽然还是被 Rust 吊打,毕竟 Rust 的宏就是一个标准 Rust 函数,里面可以为所欲为)

Rust 除了宏,还有 trait 可以做元编程,不过暂时没觉得非常惊艳。(而且印象中 trait 和 async 的配合相对会局限一些,所以感觉更不值得吹嘘这一点)

代码结构和可见性

Rust 里,各个 module 组成了树形结构,官方也确实提倡把 module 结构映射到操作系统的文件系统里,因此很清晰。每个 item (即 module, function, struct, enum, trait 等)都有可见性( public or private?),子 module 默认可以访问父 module 的 item 。其他情况下,module A 可访问 module B 的 item ,当且仅当 A 和 B 的最近公共祖先到 B 的路径上,每个 module 都是 public ,并且欲访问的 item 也是 public 的。

我很喜欢的一点就是,父 module 里的 private items ,在子 module 里是可以访问的,这就好像我有一个很大的功能模块,这个功能模块有若干子模块,我可以在这个功能模块里定义一些不想暴露给外界,但是子模块里又需要使用的东西。其他语言很难做到这样,他们如果想让子模块访问父模块的东西,就只好让父模块里的东西 public ,但是这样子就不仅仅只暴露给了子模块,还暴露给了外界。

C/C++ 里,可以透过头文件来控制可见性,也可以用 public, protected, private 来控制。但是由于不同功能模块之间没有语言级别支持的父子关系(namespace 有父子关系,但是父子关系没什么用?),就无法实现我喜欢 Rust 的那一点。不过 C++ 有友元,可以更精细的控制…… 但是我还是喜欢 Rust 这种很自然的默认设置。JS/TS 和 C# 也差不多。

Go 真的槽点太大了,靠 item 的首字母是否大写来决定可见性…… 个人反正是很讨厌。

内置数据类型

C++ 的 int, long, long long, short 分别是几个字节?跟具体的 CPU 相关,并不是定死的。

Go 里有 int8, uint64 等类型,直接写明这个类型占几字节,可惜除此以外,Go 里还有 intuint,又是跟 CPU 相关的。Rust 里,每个整数类型都写明了占几字节,而且没有跟 CPU 相关的整数类型。这种强制程序员指明数据长度的设计,我很喜欢,这样子大大提高跨平台的可能性。同时,Rust 里也有 引用/指针 类型,这个确实是跟 CPU 相关的(也不得不跟 CPU 相关),但是至少 引用/指针 类型不是整数类型。

总结

个人粗浅的理解:Rust 披着高级语言的外衣,实际上高层、底层的事情都能做,是一门严谨的、高效的、语法现代化的、安全的编程语言。个人用了一段时间,真的感觉很舒服。开发时最喜欢干的事情就是写宏(没错我就是宏孩儿)来解耦,写完了一个宏之后,用起来的感觉是真的爽,一行简单的代码,生成了一堆复杂的代码,很有成就感,代码维护成本也大大降低(不过宏维护起来确实也难一点)。

欢迎大家补充以及指正我的错误!!

2054 次点击
所在节点    编程
27 条回复
wlingxiao
34 天前
这不学一手 Scala (狗头
yoiteshaw
34 天前
写得不错,rust 带给程序员的安全性,是很棒的。但是每次都要 unwrap 让我很烦,不够优雅。(可能是我掌握不到位
StarsunYzL
34 天前
工具链
C++除了没有靠谱的包管理器外哪里差了

错误处理
C++23 有 std::expected<T, E>,C++11 可以用微软 VC 团队成员开源的 tl::expected<T, E>实现

元编程
先把 C++的 template 玩明白了再夸其他的

代码结构和可见性
过于主观

内置数据类型
C++几百年前就有了固定长度的(u)int8_t/16/32/64 类型
NPC666
34 天前
其实 C++上手难度比 Rust 高多了,Rust 如果不和 C/C++的 binding 交互,只写 rust safe 的话,开发体验是非常棒的。
liuran
34 天前
还有 rust 放弃了 C++和其他过去的面向对象语言的 Class ,而是采取 trait ,这一点和 go 的鸭子类型类似,我都感觉是非常好的实现方式,从个人体验上来说,灵活性和使用体验都比 Class 好很多。

但是工作中是写 C++的,个人项目目前还没有什么好的要用 rust 写的项目,于是总是在入门 rust 之后忘掉,下次再入门再忘掉的循环中度过。。。
bunny189
16 天前
老哥,能问问你是怎么入门的吗?先看圣经还是其他资料呀?
ciaoSora
15 天前
@bunny189 我是看了 rust 官网推荐的 Rust Book 和 Rust by example ,入门之后就可以直接看 Rust Reference 和 Rust Nomicon 了

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1065573

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX