一个月前的 太搞了 这几天录个视频

写代码不能无限信任人,只有在规则和制度的约束下,才能让人写的代码走得更远
C++一直在增加各种规范,包括其他语言也是,Java的各种规范,Python的规范等
语言本身信任人类,结果不好好写代码,后果就变成现在这种情况了
rust在设计上就选择不完全信任人类,定义了所有权,生命周期等规则来约束人,只要大家能征服编译器,基本就能写出"安全"的代码,不必担心运行时出现各种问题
虽然不能说rust的设计是工程实践上的最佳方案,但至少在很大程度上能让人类写出安全的代码
rust更像是理想和现实的一种折衷。理论上大家都希望能最大程度控制硬件资源,但是大多数人的能力有限把握不住汇编甚至是C++,尤其是软件规模的复杂度超出了人类的认知边界
rust有效地帮我们拓展了这个认知边界,虽然这个拓展的边界对C++大佬而言不值一提,但是大佬毕竟是少数人,至少80%的人还是需要这种拓展的边界的
我们也需要辩证地看待rust,有利就有弊,弊端就是rust比较费脑子,费时间,单单就这两点就可以劝退一大批人,所以留下来继续写rust的人并不多
注:
Rust 最大的特点是坚持原则,不符合的就不行
Rust默认的是没有内存问题和错误访问,并非默认没有逻辑问题
rust这种显式加类强制不是更安全吗,不过都比try catch 这种 exception 处理好就是了
try/catch的异常抛出是隐式失控的错误流,把错误处理和正常逻辑强行割裂,还容易漏处理
Rust/Haskell的类型化错误封装(Result/Maybe)是显式把错误纳入类型系统,让错误处理成为编译期强制的逻辑分支,从根源避免漏处理且代码流更清晰
C++(try/catch 写法)
#include <iostream>
#include <stdexcept>
// 除法函数,错误时抛异常
int div(int a, int b) {
if (b == 0) throw std::runtime_error("除零错误");
return a / b;
}
int main() {
int a = 10, b = 0;
// 显式包裹才会捕获,漏写try/catch直接崩溃
try {
int res = div(a, b);
std::cout << res << std::endl;
} catch (const std::runtime_error& e) { // 需匹配异常类型,漏匹配仍崩溃
std::cerr << "错误:" << e.what() << std::endl;
}
return 0;
}
核心问题:错误是「运行时抛射」,编译期无提示,漏捕获/类型匹配错直接程序崩溃,错误处理与正常逻辑割裂。
Rust(Result 类型封装)
// 除法函数,返回Result类型:Ok(结果) / Err(错误信息)
fn div(a: i32, b: i32) -> Result<i32, &'static str> {
if b == 0 {
Err("除零错误") // 错误作为返回值,而非抛射
} else {
Ok(a / b)
}
}
fn main() {
let a = 10;
let b = 0;
// 编译期强制处理错误:不处理Result,编译器直接报错
match div(a, b) {
Ok(res) => println!("{}", res),
Err(e) => eprintln!("错误:{}", e),
}
// 也可使用?/unwrap等语法,仍需显式处理,无隐式失控
// let res = div(a, b).unwrap(); // 主动unwrap,错误时panic(显式而非隐式)
}
优势:错误是「类型化返回值」,编译期强制处理,不写错误分支代码无法编译,错误流与正常逻辑统一在类型系统中。
对比
-
try/catch:错误藏在背后突然跳出来,你得主动"守着"(写try)才接得住,没守到就直接翻车;
-
Result类型:错误明着递到你手上,编译器逼着你"接过来处理",不接连门都不让出(编译不通过