文章摘要
文章核心内容是:编译器是程序员最好的朋友,开发者应该诚实对待编译器,不要试图欺骗它,这样才能获得更好的代码质量和性能优化。作者强调与编译器建立信任关系的重要性。
文章总结
编译器是你最好的朋友,别再欺骗它了
文章概述
这篇文章探讨了开发者与编译器之间的关系,指出开发者常常通过使用null、异常、类型转换和副作用等方式“欺骗”编译器,导致编译器无法充分发挥其作用。作者建议开发者应停止这些行为,转而与编译器建立更诚实、更合作的关系,从而获得更好的代码安全性和开发体验。
主要内容
编译器的角色
- 编译器是将源代码转换为目标代码的工具,其核心步骤包括解析、类型检查、优化和代码生成。
- 类型检查是开发者与编译器交互最频繁的部分,但开发者常常通过忽略类型系统的限制来“欺骗”编译器。
常见的“欺骗”行为
null的使用:声明变量为某种类型(如String),但实际上运行时可能为null,导致NullPointerException。- 未检查的异常:方法声明返回某种类型,但实际上可能抛出异常,编译器无法跟踪这些异常。
- 类型转换:开发者“知道”某个变量的实际类型,强制进行类型转换,但未来代码变更可能导致运行时错误。
- 副作用:函数没有明确声明其副作用(如修改状态或写入文件),导致编译器无法帮助管理这些行为。
停止欺骗编译器的好处
null的处理:使用Option或Maybe类型明确表示可能缺失的值,编译器会强制处理null情况。- 异常的处理:使用
Result或Try类型明确表示可能失败的操作,编译器会强制处理错误情况。 - 避免类型转换:通过更精确的类型设计(如密封类或联合类型)替代类型转换,编译器可以更好地跟踪类型。
- 管理副作用:将纯计算与副作用分离,使编译器能够更好地理解和优化代码。
与编译器合作的高级技巧
- 类型包装:为领域概念(如
UserID、AppID)创建专用类型,避免原始类型(如int、string)的混淆。 - 联合类型:使用联合类型或密封类明确表示所有可能的状态,编译器可以确保所有情况都被处理。
- 类型保证:通过类型系统编码不变式(如
NonEmptyList、PositiveNumber),编译器可以自动验证这些不变式。
- 类型包装:为领域概念(如
实际意义
- 通过诚实对待编译器,开发者可以减少运行时错误,提高代码的可维护性和安全性。
- 文章以谷歌云2025年6月的故障为例,说明
null导致的系统崩溃如何通过更严格的类型设计避免。
结论
编译器是开发者的强大盟友,但只有当我们停止欺骗它并充分利用其能力时,才能发挥其最大价值。通过更精确的类型设计和与编译器的合作,开发者可以编写更安全、更可靠的代码,同时减少调试和维护的负担。
评论总结
以下是评论内容的总结:
关于异常处理与程序崩溃
- 观点:当遇到无法恢复的内部逻辑错误时,直接崩溃可能是最简单的解决方案。
- 论据:
- "At some level, the simplest thing to do is to give up and crash if things are no longer sane."
- "Logging can typically be done just fine within a top-level exception handler or panic handler in many languages."
编译器与规则
- 观点:编译器严格遵循规则,这是形式化系统的本质。
- 论据:
- "Programming languages are a formal notation for the execution steps of a computing machine."
- "You either follow the rules or you do not and have an error."
类型系统的优势与挑战
- 观点:强类型语言(如Swift、Rust)能减少错误,但类型系统设计不当可能增加复杂性。
- 论据:
- "Functional languages like ML/Haskell/Lisp dialects has no lies built in for decades."
- "If they get the model wrong, or it is incomplete then you aren't really gaining much out of a strictly typed language."
编程语言趋势与批评
- 观点:现代编程语言(如Rust)过度强调类型系统,可能导致抽象过度。
- 论据:
- "The type system is the program, rather than the program being the program."
- "It ultimately feels to me like a barrier between intention and reality."
内存管理与语言比较
- 观点:Rust的内存管理优于C/C++,但C++通过智能指针已大幅改善。
- 论据:
- "In C++, memory management has not been a pain point for many years."
- "The safety and no-UB constraints prevent a lot of that (zero-cost abstractions)."
代码验证与AI的作用
- 观点:AI可能使形式化验证更普及,但当前工具仍复杂。
- 论据:
- "AI has made making code proofs or 'formal verification' more accessible."
- "Actually writing a proof for your code is very hard to do for most programmers."
软件复杂性与依赖问题
- 观点:现代软件生态依赖过多,工具链臃肿,复杂性失控。
- 论据:
- "We ended up worshipping more and more bloat. Nobody cares about size."
- "Why is rust suddenly such a huge dependency? Why is there such a proliferation of programming languages?"
实用编程技巧
- 观点:使用断言(assert)处理“不可能发生”的情况是基本编程技巧。
- 论据:
- "My code is peppered with
assert(0)for cases that should never happen." - "When they trip, then I figure out why it happened and fix it."
- "My code is peppered with
功能核心与命令式外壳
- 观点:分离业务逻辑与副作用(如数据读写)是理想实践,但实际应用困难。
- 论据:
- "The code feels very messy and procedural, with business logic mixed with side effects."
- "I'm not sure where a natural separation point would be."
语言特性建议
- 观点:应更多语言支持显式空值标记(如C#的可空引用类型)。
- 论据:
- "C# has the concept of nullable reference types which requires you to be explicit if a variable can be null."
- "I would love to see a similar feature in languages like TypeScript and Go."
总结涵盖了评论中的主要观点和争议点,保持了不同视角的平衡,并引用了关键语句以支持总结内容。