Skip to content

语言对比

已收录:本页沉淀 JavaScript / TypeScript / Python / Go / Rust 五门语言的对比笔记,覆盖「相同问题的不同解法」与「选型考量」。各语言的示例与踩坑细节请进入对应语言页:JavaScriptTypeScriptPythonGoRust

五句话定位

语言定位一句话印象
JavaScriptWeb 全栈事实语言单线程事件循环 + 动态类型,浏览器里唯一的选择
TypeScriptJS 的超集(静态类型层)把 JS 的「自由」框进类型系统,大型前端标配
Python胶水语言与数据科学语法最易读、生态最广,性能靠 C 扩展兜底
Go云原生后端与 CLI极简 + goroutine,把「并发」写成寻常语法
Rust系统级性能与安全零成本抽象 + 编译期内存安全,代价是陡峭学习曲线

总览对照表

维度JavaScriptTypeScriptPythonGoRust
类型动态静态(结构化/可推断)动态(渐进注解)静态(简单强)静态(强 + trait)
内存管理GC(V8)同 JS引用计数 + GCGC(并发标记)所有权 + 编译期析构
运行模型解释/JIT编译为 JS解释(CPython)编译为原生编译为原生
并发原语单线程 + 事件循环 + Worker同 JS线程 + GIL / asynciogoroutine + channel线程 / async,编译期检查
空值表示undefined / null联合类型收窄None零值 + errorOption<T>
错误处理异常 throw同 JS异常 raise多返回值 + errorResult<T, E>
多态鸭子类型结构化类型鸭子 + ABC隐式接口trait 显式实现
包管理npm / pnpm同 JSpip / uvgo modcargo
构建/检查无编译(bundler)tsc无编译go buildcargo build
测试框架生态(Jest/Vitest)同 JSpytest(stdlib unittest)内建 go test内建 cargo test
进入成本最低
适用主力场景前端、Node 服务前端工程、Node 服务脚本、数据、AI后端 API、中间件、CLI性能关键、系统、基础设施

同题异解:相同问题,不同解法

① 集合变换:1..10 中偶数求和

js
// JavaScript
[...Array(10)].map((_, i) => i + 1).filter(x => x % 2 === 0).reduce((a, b) => a + b, 0)
// 30
ts
// TypeScript(与 JS 运行时等价,编译期只剥类型)
const sum: number = Array.from({ length: 10 }, (_, i) => i + 1)
  .filter(x => x % 2 === 0)
  .reduce((a, b) => a + b, 0)
py
# Python:生成器表达式最直观
sum(x for x in range(1, 11) if x % 2 == 0)  # 30
go
// Go:无流式 API,手写循环是惯例
sum := 0
for i := 1; i <= 10; i++ {
    if i%2 == 0 {
        sum += i
    }
}
rust
// Rust:迭代器链(惰性,零分配)
(1..=10).filter(|x| x % 2 == 0).sum::<i32>() // 30

差异本质:JS/TS/Python/Rust 倾向「描述要什么」的声明式链式;Go 倾向「描述怎么做」的命令式(标准库刻意少魔法、类型简单)。Rust 的链在编译期内联、无中间分配,与 Go 手写循环性能相当。

② 可选值 / 空值(null safety 光谱)

js
// JavaScript:任何位置都可能 undefined,靠 ?. 与 ?? 兜底
const u = maybeUser(0)
const name = u?.name ?? '匿名'          // 匿名
py
# Python:None 可出现在任何值上,靠 if 判断
u = maybe_user(0)
name = u["name"] if u else "匿名"
go
// Go:返回 (值, ok) 二元组,零值(nil map)不可直接读
func findUser(id int) (map[string]int, error) {
    if id <= 0 { return nil, errors.New("无效 id") }
    return map[string]int{"id": id}, nil
}
u, err := findUser(0)
rust
// Rust:Option<T> 是普通类型,match/?/map 强制处理
fn find_user(id: i32) -> Option<User> {
    (id > 0).then(|| User { id })     // 编译器不允许忽略 None 分支
}
语言空值语义忘记处理的后果兜底写法
JS/TSundefined/null 双空值运行期 undefined is not a function?.??
TS(strict)类型系统可排除编译期报错收窄 if (u) {}
PythonNone运行期 AttributeErrorif xor 默认
Go零值 + 显式 error运行期 panic(nil 解引用)comma-ok、err != nil
Rust编译期类型编译期报错(穷尽匹配)Option/Result 组合子

光谱从「运行期才能发现」(JS/Python) 到「编译期强制」(Rust/TS-strict)。Go 介于其间:nil 能编译但运行期炸,靠纪律约定。

③ 错误处理哲学

语言机制优点代价/坑
JS/TS异常 throw/catch栈自动带上下文忘记 catch 程序崩溃;类型不标注错误种类
Python异常内置丰富(ValueError…)异常即控制流易滥用;性能开销
Goerror 值 + 显式 if错误是普通值,流清晰样板多(if err != nil 满天飞)
RustResult + ?类型化错误,? 自动 From 转换自定义错误枚举需要样板(thiserror 缓解)
go
// Go:处理每个错误是默认姿态
f, err := os.Open(path)
if err != nil { return err }
rust
// Rust:? 把「成功继续 / 失败上抛」压成一行
let f = File::open(path)?;   // io::Error → 自动转成函数返回的错误类型

Rust 的 ? 本质是「Go 的 if err 的语法糖 + 自动类型转换」;Go 坚持显式换来简单一致,Rust 坚持类型化换来可组合。

④ 多态与接口

ts
// TS:结构化类型(鸭子类型 + 静态检查)
interface Speaker { speak(): string }
function greet(s: Speaker) { console.log(s.speak()) }
py
# Python:鸭子类型(运行期),ABC 提供约束
def greet(s):
    print(s.speak())   # 只要会 speak() 就行
go
// Go:隐式接口——类型实现方法即自动满足,无需声明
type Speaker interface{ Speak() string }
func greet(s Speaker) { fmt.Println(s.Speak()) }
rust
// Rust:显式 trait——必须写出 impl,编译期约束最严
trait Speaker { fn speak(&self) -> String; }
fn greet(s: &dyn Speaker) { println!("{}", s.speak()); }
语言实现关系声明检查时机
JS结构匹配无需运行期(鸭子)
TS结构匹配无需(implements 可选)编译期
Python结构匹配 / ABC 注册可选(ABC)运行期
Go结构匹配(方法集)无需声明编译期
Rust名义 + 结构(trait 实现处声明)必须 impl编译期

同一条光谱:JS → Python → TS → Go 靠「形状一致」,Rust 最明确(写 impl Speaker for Dog),代价是代码多、换来方法集与 trait bound 的精确性(孤儿规则、对象安全等编译器保障)。

⑤ 并发:两个任务并行 + 等结果

js
// JavaScript:单线程事件循环,Promise.all 并发 IO
const [a, b] = await Promise.all([fetch(1), fetch(2)])
py
# Python:asyncio 单线程事件循环(与 JS 同构)
a, b = await asyncio.gather(fetch(1), fetch(2))
go
// Go:goroutine + channel,阻塞式同步写法,天然并行
ch := make(chan int, 2)
go fetch(1, ch); go fetch(2, ch)
a, b := <-ch, <-ch
rust
// Rust:async 显式 + 运行时(tokio),join! 并行等待
let (a, b) = tokio::join!(fetch(1), fetch(2));
语言并发模型线程→语言能力并行(多核)前提
JS事件循环(单线程)无共享内存Worker 线程(消息传递)
Python线程(GIL)+ asyncioGIL 限制 CPU 并行multiprocessing/C 扩展释放
Gogoroutine(M:N,CSP)语言一等公民默认多核,GOMAXPROCS 自动
Rust系统线程 + async 运行时Send/Sync 编译期检查线程直接并行,无锁数据靠类型

关键差异:JS/Python 的 async 是协作式单线程(不能真并行 CPU 计算);Go 的 goroutine 是运行时调度的 M:N 并发,channel 同步风格;Rust 要求你显式选择「线程 or async」,并把数据竞态挡在编译期。选型时先问「我要的是并发 IO(JS/Go 都行)还是多核并行计算(Go/Rust/多进程)」。

选型考量

场景 → 推荐

场景首选理由备选
Web 前端 / 跨端TypeScript唯一全生态、类型安全
Node 后端 APITypeScript与前端同语言,生态成熟Go(性能更高)
常规后端服务 / 微服务Gogoroutine 简单、部署单二进制、云原生生态(K8s 系)Rust(更高性能要求)
高吞吐基础设施 / 系统组件Rust性能与内存安全,无 GC 停顿Go(开发更快)
数据处理 / AI / 脚本自动化Python生态统治(numpy/pandas/torch)、迭代最快
CLI 工具 / 运维小工具Go 或 Rust单文件静态分发、启动快Python(要装解释器)
嵌入式 / FFI / 追求极致性能Rust无运行时、可裸机C(遗留)
快速原型验证Python / TS最少代码量最快改

决策清单(选型自问)

  1. 团队会什么——语言生态与招人成本往往 > 语言本身的优劣;
  2. 瓶颈在哪——IO 密集选 goroutine/async 就够;CPU 密集才需要 Rust/Go 级并行与低开销;
  3. 可靠性要求——错误路径多、崩溃代价高的系统值得用 Rust/TS strict 把问题前移到编译期;
  4. 部署形态——「一个二进制到处跑」选 Go/Rust;「随叫随到的脚本」选 Python;
  5. 共享代码——前后端一体用 TS 全栈;别为「酷」引入第二门语言,除非有清晰收益;
  6. 生态成熟度——先查目标领域库是否完善(数据科学=Python、云原生=Go、前端=TS、嵌入式= Rust/C)。

常见误区

  • 「Rust 更快所以服务全用 Rust」——多数 Web 服务的瓶颈是 IO 与数据库,Go 的开发效率优势更值钱;
  • 「Python 太慢不能做后端」——GIL 内做 IO 并发(asyncio/多线程)足够服务大量连接,瓶颈通常在 DB;
  • 「JS 单线程做不了并行」——Worker/子进程可用,但「计算并行」不是 JS 主场,别硬掰;
  • 「TS 只是加类型」——类型系统还能表达可选性、区分度(字面量/模板类型),设计好了防一半运行期 bug;
  • 「Go 没有泛型/异常所以落后」——Go 1.18+ 有泛型;error 值哲学换来的是全代码库一致的错误流,是取舍不是缺陷;
  • 「Rust 所有权只是借用检查器添乱」——它把内存管理变成类型问题:数据结构设计对了,&/&mut/Owned 自然顺畅。

状态与参考

  • 状态:已收录(2026-09-02,继五门语言页之后完成跨语言对照)。
  • 运行环境:JS 示例基于 Node v20(TS 与 JS 运行时等价);Python 示例 Python 3;Go 示例 Go 1.26;Rust 示例 rustc 1.98 —— 集合变换与可选值示例均经实跑验证,输出见各小节注释。
  • 参考:本模块各语言页(JS / TS / Python / Go / Rust)。

下一步

  • [ ] 补充「同题异解」更多问题:字符串处理、日期时间、配置读取、JSON 序列化的五语言对照
  • [ ] 对照「编译原理入门」规划,沉淀静态类型系统(TS/Go/Rust)之间的类型检查差异笔记
  • [ ] 沉淀「跨语言协作」约定:同一 codebase 多语言边界(前端 TS、后端 Go、脚本 Python)的接口契约

写作规范与页面规划请参阅领域概览

基于 VitePress 构建 · 内容以知识共享方式沉淀