从 PHP 到 Go:最难重塑的思维方式
我写了七年 PHP。其中五年都在使用 Laravel。当我转向 Go,负责将一个 Laravel 单体架构迁移到微服务架构时,我带来的不是教程,而是十年的 PHP 习惯。
学习语法很容易。一个下午你就能看懂 Go。难点在于“忘掉”原有的编程思维。
以下是我花了数月时间才掌握的思维转变:
错误处理 (Error Handling) 在 PHP 中,我使用
try/catch。错误通常会隐形地传递到全局处理器。在 Go 中,错误是值。函数会将错误作为最后一个返回值。你必须当场处理它。起初,这感觉像是额外的工作。后来我意识到,它让失败变得可见。当服务发生故障时,错误信息就像是一串面包屑轨迹。它能准确告诉你故障发生的位置,而不需要庞大的堆栈追踪。内存与状态 (Memory and State) PHP 使用“无共享”(shared-nothing)模型。每个请求都从一个干净的状态开始。内存泄漏没那么重要,因为进程在请求结束后就会销毁。Go 则不同。进程会持续运行,处理成千上万个请求。这意味着包级变量(package-level variable)在所有请求之间是共享的。如果两个请求尝试同时写入一个 map,整个程序就会崩溃。在 Go 中,你需要掌控并发。你必须使用 race detector 等工具来保证安全。
Context 的角色 (The Role of Context) 在 PHP 中,请求就是边界。当请求结束,一切停止。在 Go 中,没有任何东西会自动停止。如果客户端断开连接,你的 goroutine 可能会继续运行并浪费资源。你必须使用
context.Context在代码中传递取消信号。它是让你的服务在高负载下保持健康的核心支柱。组合优于继承 (Composition Over Inheritance) Laravel 高度依赖于扩展基类。你通过继承行为来增加功能。Go 没有类继承。它使用隐式实现的接口(interfaces)。你在需要的地方定义你所需的内容。这使得代码更易于测试和替换。为了写好 Go,我不得不扼杀那种“想要扩展一切”的本能。
清晰优于巧妙 (Clarity Over Cleverness) PHP 允许使用魔术方法(magic methods)和动态类型。你可以写出巧妙且富有表现力的代码。Go 是刻意追求“枯燥”的。编译器强制你使用标准格式,并防止使用未定义的变量。起初,这感觉很受限。现在,我非常看重这一点。Go 是为代码的阅读者优化的,而不是为编写者优化的。在凌晨两点的突发故障中,枯燥的代码更容易修复。
学习一门新语言的难点不在于新语法,而在于你随身携带的旧假设。
Source: https://dev.to/econ__11/from-php-to-go-what-took-me-longest-to-rewire-2nfn
