blog
blog copied to clipboard
Comparative Analysis: Rust vs Golang vs Python
related:
- [x] https://github.com/better-rs/learn-rs
- [x] #343
- [x] #247
- [x] #242
比较分析: Rust vs Golang vs Python
- 对比学习, 是一种高效的学习方法.
说明:
- 通过对比不同语言的特性设计上的异同点, 快速学习 Rust.
- 以其他语言辅助理解 Rust 的特性.
Rust 语言特性与其他语言对比:
- 优选 Python / Golang / Java 等主流/特性完备的语言做对比.
- 一个是熟悉的人比较多
- 一个是特性完备
- 语言设计, 是有发展历史的. 很多特性, 都是从其他语言借鉴/迭代而来.
关于比较分析法
:
- https://www.indeed.com/career-advice/career-development/comparative-analysis
- https://en.wikipedia.org/wiki/Comparative_research
- https://en.wikipedia.org/wiki/Comparative_method
Rust 核心亮点:
- mut: 区分 变量的默认
读写
权限, 非常聪明的设计. - trait: 非常
精巧
的在静态语言, 实现了go interface
的效果, 且易用性
不输 go interface.- 考虑 rust 是静态语言, 实现上的困难程度.
- 熟悉 go interface, 就更容易理解 trait 的巧妙之处.
- 泛型(generics): c++/dart 等基操.
- 宏(macro): c 语言概念, 用于实现代码生成器(类似 go generate), 以及更强大的功能.
- Option/Result: 非常聪明的返回值处理. 对比 go
err!=nil
, 聪明太多.- https://doc.rust-lang.org/rust-by-example/error/multiple_error_types/option_result.html
- 类型标注: 人工标记, 辅助编译器推导类型.
- cargo: 超高质量的工具链, go 相对拉胯(半残).
- FFI(Foreign Function Interface): 超强的跨语言(支持 C ABI)互通能力, 工具链完善.
- 基于 Rust 的 core lib 层设计, 实现超强的跨平台代码复用.
- 内存安全
- 并发
- 交叉编译
- 零开销抽象能力
Rust 比较糟糕的设计:
- Rust 内一些糟糕的设计, 阻碍 Rust 的广泛传播.
- 个人看法, 比较主观.
- 表达式返回值.
- 这个设计, 带来的优点, 就是
一行流
, 能写更短的代码. (短 ≠ 易读) - 但是缺点非常多:
- 是隐式设计, "很不显然".
- 破坏语言的简单性.
- 需要知道
带 ;
(语句) 和不带 ;
( 表达式 = 隐含 return xxx).- 这对非 Rust 语言开发者理解 Rust, 带来巨大障碍.(且是非主流/通用设计)
- 所有人都可以不学 Javascript 语法, 都可以改 JS 代码, 是因为 JS 没有太多让人
惊讶
的设计规则.
- 隐含不同的效果.
- 这个设计, 带来的优点, 就是
- loop/for/while, 比较冗余.
- 糟糕的符号学审美.
- Rust 恨不得把所有的键盘符号, 都用个遍!
-
!, @, ', ., ::, =>, ->, ?, :, |, _, | |, (), <>, [], {}, .., {:?}, $, &, *, ;, #[], //,
- 请注意, 这些符号, 都是 Rust 合法使用 + 经常使用的.
- 当你看到满眼的这些符号, 脑壳疼不疼?
-
- 大量符号, 影响代码阅读效率. 增加学习成本.
- Rust 恨不得把所有的键盘符号, 都用个遍!
- 大量隐式约定规范: 这些特性本身没问题. 问题在于是隐式的约定. (非语言背景者, 无从知晓)
- mod.rs 文件, 特殊文件. 这个类似
__init__.py
. 用于模块导出. - lib.rs 文件, 特殊文件. 这是 lib 类项目入口. 用于集中导出模块.
- bin/ 文件夹, 特殊. 用于添加 bin 执行文件.
- tests/ 文件夹, 特殊. 用于集成测试.
- cargo 支持的自定义指令, 隐式. 需要查阅文档才能知晓.
- 宏的使用. 不了解宏的特性, 无法理解涉及宏部分的代码.
- mod.rs 文件, 特殊文件. 这个类似
Rust 语言特性与其他语言对比:
- 默认是熟悉其他语言的特性
- 不会过多解释其他语言的设计细节, 着重解释 Rust 的差异点.
- Rust 是大量语言优秀特性的集大成者.(当然也继承了部分糟粕)
注意:
- 部分涉及内存(copy/move) 相关的表述, 不严谨. 欢迎补充完善.
- 后续会逐步细化差异.
Why Python?
- https://www.python.org/
- Python 非常简单, 掌握 Python 的开发者非常多.
- Rust 借鉴了很多 Python 的设计(元组/mod.rs/等)
- 合理猜测 Rust 早期设计者中有人非常精通 Python.
Why Golang?
- https://go.dev/
- Golang 用户非常多, 且 Golang 用户, 是 Rust 最大的潜在用户群.
- 在意性能提升
- Rust 非常巧妙的实现了 Go Interface, Goroutine, Channel 等概念.
- 非常适合对比学习.
Why C++?
- http://www.open-std.org/JTC1/SC22/WG21/
- https://www.cplusplus.com/
- 几百年不打开看一下, 这网站透露着远古气息扑面而来.
- Rust 最早的核心目标: 替代 C++, 吸引 C++开发者(这个失败了).
- 为什么 Rust 无法吸引大量 C++ 开发者?
- 核心原因: 操练 Rust 和 C++, 都要花费巨大精力, 已精通 C++的开发者, 放弃 C++ 的沉默成本过高.
- Rust 注定无法吸引 C++ 主体开发者. 相反, 更容易的是 Python/Golang/Java 开发者.
- Rust 和 C++ 在语言完备性上, 基本等价.
- Rust 基本是 C++ 的优化版, 主体设计, 都是以更好的方式, 实现 C++ 的特性.
Why Haskell?
- https://www.haskell.org/
- Haskell 是函数式语言(lisp)的代表.
- Rust 借鉴了函数式语言的大量特性.
- https://www.fpcomplete.com/blog/philosophies-rust-haskell/
特性对比:
- 鉴于只对 C++ 11 标准比较熟悉, 之后不关注 C++ 发展. 无法充分对比 C++.
- 有熟悉C++ 的, 欢迎补充.
Rust | Python | Golang | C++ | Haskell | 备注 |
---|---|---|---|---|---|
基础数据类型 | xxxxxxxxxxxxxxxxxx | xxxxxxxxxx | xxxxxxxxxx | xxxxxxxxxx | xxxxxxxxxx |
struct | 对应 class | go 类似, 用作类型设计<数据+行为> | xxxxxxxxxx | xxxxxxxxxx | rust 的 struct, 设计和使用方式上和 go 非常像 |
trait + impl | 抽象类 | ≈ interface 接口类型. 区别是 trait 可以含默认接口实现 | xxxxxxxxxx | xxxxxxxxxx | rust 是显示声明 impl 实现一个 trait, go 是隐式实现. |
泛型 | 动态语言, 鸭子类型, 无需 | go1.8 添加支持 | xxxxxxxxxx | xxxxxxxxxx | rust 的泛型设计, 非常简洁 |
宏 | xxxxxxxxxxxxxxxxxx | go 的代码生成器(generate) | xxxxxxxxxx | xxxxxxxxxx | xxxxxxxxxx |
类型标注 | xxxxxxxxxxxxxxxxxx | xxxxxxxxxx | xxxxxxxxxx | xxxxxxxxxx | xxxxxxxxxx |
模块(mod.rs) | 类 __init__.py 文件 |
无, 默认一个文件夹, 为一个 module | xxxxxxxxxx | xxxxxxxxxx | rust 这个 模块设计, 接近 Python, 范围控制颗粒度更细 |
模块作用域范围 | 文件内 | 文件夹内(共享作用域/隐式可见) | xxxxxxxxxx | xxxxxxxxxx | rust 使用 mod 关键字控制, 默认是文件内可见, 通过 mod 显式导入 |
内存所有权(ownership) | 无明确概念 | xxxxxxxxxx | xxxxxxxxxx | xxxxxxxxxx | 类似 c/c++ 内存概念 |
变量生命周期 | xxxxxxxxxxxxxxxxxx | xxxxxxxxxx | xxxxxxxxxx | xxxxxxxxxx | xxxxxxxxxx |
变量类型标注 | 类似 type hint, 区别: 约束 vs 编译器 check | 无 | xxxxxxxxxx | xxxxxxxxxx | xxxxxxxxxx |
move vs copy 语义 | 无需关注 | 引用类型 vs 值类型 | xxxxxxxxxx | xxxxxxxxxx | 复制 vs 引用, 基本同 c/c++ 的指针概念 |
单元测试 | 测试方法以 test 为前缀 | xxxxxxxxxx | xxxxxxxxxx | xxxxxxxxxx | #[cfg(test)] #[test] 标注测试方法 |
集成测试 | pytest, unittest 包 | _test.go 后缀 | xxxxxxxxxx | xxxxxxxxxx | rust 隐含 tests 文件夹, 是集成测试专用 |
cargo | pip 包管理工具 | go mod 包管理工具 | xxxxxxxxxx | xxxxxxxxxx | rust 包管理工具 |
cargo bin | __main__ 隐式入口 |
main() 函数入口 | xxxxxxxxxx | xxxxxxxxxx | cargo bin 是二进制类型项目 |
cargo lib | python 常规的 lib 项目就是, 无特别约束 | xxxxxxxxxx | xxxxxxxxxx | xxxxxxxxxx | cargo lib 是库类型项目 |
https://crates.io/ | https://pypi.org/ 包托管平台 | 无, 依赖 github.com 实现包获取 | xxxxxxxxxx | xxxxxxxxxx | rust 官方包托管平台, 自带 docs 托管 |
https://docs.rs/ | 无, 项目方自行维护 | 无, 项目方自行维护 | xxxxxxxxxx | xxxxxxxxxx | rust 文档托管平台 |
xxxxxxxxxx | xxxxxxxxxxxxxxxxxx | xxxxxxxxxx | xxxxxxxxxx | xxxxxxxxxx | xxxxxxxxxx |
xxxxxxxxxx | xxxxxxxxxxxxxxxxxx | xxxxxxxxxx | xxxxxxxxxx | xxxxxxxxxx | xxxxxxxxxx |
xxxxxxxxxx | xxxxxxxxxxxxxxxxxx | xxxxxxxxxx | xxxxxxxxxx | xxxxxxxxxx | xxxxxxxxxx |
xxxxxxxxxx | xxxxxxxxxxxxxxxxxx | xxxxxxxxxx | xxxxxxxxxx | xxxxxxxxxx | xxxxxxxxxx |
xxxxxxxxxx | xxxxxxxxxxxxxxxxxx | xxxxxxxxxx | xxxxxxxxxx | xxxxxxxxxx | xxxxxxxxxx |
xxxxxxxxxx | xxxxxxxxxxxxxxxxxx | xxxxxxxxxx | xxxxxxxxxx | xxxxxxxxxx | xxxxxxxxxx |
1
1
1