PHP转Go,思维先行!

183 阅读4分钟

如果你熟知PHP,学习Go语言的关键一定不在Go语言的语法上,而是在你的思维认知上,从PHP转Go有太多的思维需要转换,当然对于Java程序员来说,可能会好一些

我本身是一位10+年的PHP工程师,甚至还熟悉JavaScript/c/c++等语言,但是在转换到Go的过程中,仍然会遇到不少思维墙,本文会从以下几个方面分别去论述:

  • 弱类型到强类型的转换
  • 非常驻内存到常驻内存的转换
  • 单进程到并发协程的转换
  • 全局 try catcherror 的转换
  • 解释型语言到编译型语言的转换

弱类型到强类型的转换

何为强类型?最关键一点其实就是要显示的指定任何一个变量的类型

比如在php中,我们经常会定义一个变量 $a = 1 或者 $a = "1",这都是正确的语法,并且你都可以正确执行 $b = $a+1 这个代码;在php中,php解释器会推断每个变量的类型,甚至会做变量的隐式的类型转换,比如如果你将 $a = "1" 赋值为字符串,为了与+1能够完成运算,php运行库,会自动将$a转换为整数1,再完成+1运算;

所以第一个要转换的思维就是:Go是强类型语言,每个变量都要有确定的类型;这在刚写Go代码时就会感觉非常别扭,每一个请求或者响应,都要定义一个结构体,映射json字段,每有一点参数变化,都要同步去修改结构体;

是的,这件事对接触强类型语言时是很烦人的,但是要理解,强类型语言就是要这么干的

非常驻内存到常驻内存的转换

PHP在执行完相关代码后,会立即释放占用的系统资源并清理一切变量,多次请求之间是完全独立的,互不干扰,这是因为PHP是解释型语言,每次请求都要经历编译,重头执行;但是对于Go语言来说,是编译型语言,直接是二进制运行,运行起来后就不会退出,持续提供服务;当然,php借助于swoole等扩展也能实现常驻内存运行,不过并不常见;

  • 对于PHP可以通过初始化一些全局变量来进行全局变量,在任何地方都能读取
  • 对于Go语言,必须要进行参数传递,当然可以通过将多个变量存放在context中,不过这个仍然会让很多php程序员感到莫名其妙,明明是全局的东西,必须还要到处传递

单进程到并发协程的转换

在php编程中很少会涉及到多进程/线程的开发,并发编程的实现也会略复杂。但是go语言天然支持并发,并且使用起来超级简单,所以在编程过程中对于可以并行处理的一些场景,要转换思维,从串行改到合理的并行,以加快响应速度;

全局 try catcherror 的转换

无论是php还是java,甚至目前绝大多数语言,都有try catch机制,来保证程序不异常退出。但是,到了go语言中,这个机制不复存在~,golang推崇的是显式的处理一切错误,所以在任何可能发生错误的地方都要显式的处理,或者记录日志,或者向上传递返回,总之,不存在一劳永逸的全局机制。当然golang中还有panic机制,但是这个属于异常,与error概念不同,panic是处理完全不可预期的错误,比如内存越界,凡是业务中能遇见的错误,均应该是用error处理;

解释型语言到编译型语言的转换

解释型语言每次运行需要将源代码解释成机器码并执行,而编译型语言一次编译后便可以多次运行,只需要由编译器将源代码编译成可执行文件,由此可见编译型语言执行效率通常会更高;解释型语言的跨平台是由解释器来抹平的,而编译型语言则是由编译器来抹平; 从PHP切到Go,最让人无法适从的就是PHP保存后就可以访问查看效果,但是Go语言源码改变后,仍要进行一次编译,才能运行看结果,当然对于小项目来说差别不大,但是对于大项目来说,编译过程是要花费不少时间的,所以可以配合一些监控文件变动的程序,比如 air,当源文件发生变化时,自动完成编译和运行,提高编码效率;

以上是我在PHP转Go中遇到的思维变化,虽然我有C/C++的经验,但是最近10年都是在使用PHP或者JS等弱类型&解释型语言,所以一开始接受Go是蛮痛苦的一件事,当然接受后,逃离不了真香定律!

接下来我将会将我学习过程中的关键知识点持续的写成文章,期望这次能坚持下去!