抓了只水蓝色的地鼠玩玩

抓了只水蓝色的地鼠玩玩

技术 2240 字 / 4 分钟
AI 总结 以下AI总结内容由腾讯混元大模型生成

本文主要讨论了作者学习Golang语言的经历和感受。作者从最初对Golang的无感,到逐渐了解和掌握这门语言的过程,分享了心得体会。文章首先介绍了Golang的特点和与PHP的对比,然后通过实际项目练习,详细探讨了Golang在不同方面的优势和应用场景。

  1. 初识Golang:作者最初对Golang并无特别感觉,但随着对PHP自动部署功能的思考,开始对Golang产生兴趣。

  2. 编译型与解释型:Golang是编译型语言,具有打包成可执行文件的优势,而PHP是解释型语言,修改方便。

  3. Web服务器:Golang作为静态网页托管,与PHP的服务器软件如Nginx、Apache相比,具有更好的性能和便利性。

  4. 语法特点:Golang的语法独特,如函数支持多个返回值、变量必须先声明等,作者通过实际使用加深了对这些特性的理解。

  5. Gin框架:作者使用Gin框架搭建了留言板API,体验到了其便捷性和高效性。

  6. Golang的优势:通过实际项目和Gin框架的使用,作者认为Golang既有编译型的稳定性和安全性,又有动态语言的灵活性和易用性。

总的来说,作者通过学习使用Golang,不仅提高了编程技能,也对这门语言有了更深入的了解和认识。

第一次听说 Golang,还是在上学期刚加入杭电助手的时候。当时跟大家还不熟,我在群里还挺腼腆的。当时部长开了个让我记忆犹新的玩笑:

我们或许可以期待一下 Google 推出 ogle 语言。

真香

刚开始我其实一直对 Golang 无感,和部长半开玩笑半认真地吹 PHP,觉得 Go 能做的,PHP 其实也能做到。只是具体的实现方式不同罢了。 但是前阵子在折腾 PHP 自动部署时,有过写一个类似 Drone 的图形化部署界面的想法。这时,我才隐隐意识到,PHP 这种不需要编译的语言的“别扭”之处。 PHP 主要用于 Web 应用的开发,虽然她也有 CLI 模式,但毕竟不是很常用,也就 Composer 那边会用用。很多时候,为了安全考虑,我们都会选择禁用掉诸如eval system exec等函数。然而有些操作比如想使用 git 时,又不得不使用这些去执行git pull git clone,所以就很矛盾了。

之后,我了解到 Docker 居然是使用 Golang 编写的,以及知乎等一系列大厂都使用 Golang 重构后;我感觉这个语言可能确实是有点厉害啊。

初遇

于是,我逐渐开始接触这个语言。我才发现他真的有毒。 一般的语言,什么都没学,直接上来还是能看懂一些的。而这个 Go 嘛…… 这个:=是什么?怎么函数的前面,后面都有括号传参,怎么函数名后面还有两个括号??? 真的是一脸懵逼啊。 上网找了个菜鸡教程看了下,在明白了一些。卧槽,这语言居然可以有多个返回值!!这语言的语法怎么和 C 那么像!!

昨天在协会写了一天的 Go。其实是摸了一天的鱼再加上晚上部长面授 SQL 数据库操作;今天我终于用 Go 写完了一个留言板的后端 API。 自己也从中摸索到了一些东西。感觉其实只要会了数据库的增删改查,就能够写不少东西了。那借着这个契机,我来聊聊我所理解的 Go 和 PHP 的不同。

水蓝色地鼠 VS 紫色大象

编译型 / 解释型

Go 是一门编译型语言,这使得他写出来的应用是打包成一个可执行的二进制文件执行。而 PHP 则就是.php文件,然后用 PHP 解释器运行。这使得 PHP 修改起来确实方便很多,直接以文本形式打开,改完保存。而 Go 则需要重新编译一次。同时,Go 也没有像 PHP__LINE__这种属性或者eval这种很有意思的东西。但 Go 一打包出来就是二进制文件,源码得到了保护,并且因为是一个整体,我想迁移起来应该也很舒服。

Web 服务器??

用 PHP 来搭建一个 Web 应用,你总需要装诸如 Nginx 或 Apache 这样的服务器软件,来处理 HTTP 请求,并把相应的请求转发给后面的 PHP 解释器。而 Go 就只是一个可执行文件,全部都包在里面了,直接作为守护进程运行在后台即可。这应该也是为什么 Drone 部署 Go 应用都直接就是打包成一个 Docker 镜像。

语法相关

我想 Go 比较有意思的,就是他的函数可以有多个返回值。这个我感觉真的不多见。不过写了一些 Go 之后,我也能大概理解他这么做的用意的。Go 中并没有throwtry catch语句来抛出或捕获异常,全部的异常处理都是在函数中以一个error的返回值来实现的。只需要判断一下返回的error变量是不是nil,就可以知道有没有异常了。 同时,Go 为了提高性能,节省不必要的内存开销,规定变量不允许仅定义而不使用。我想因此也就产生了:=申明并赋值这么一个奇怪的操作符。 并且 Go 真的是兼具了不同语言的特点啊,这使得他有点像一个“不三不四”的结合体——虽然是一个强类型的语言,但是还具有JavaScript或者说是Swiftvarfunc关键字。同时又是类型后置,需要在变量名后输入变量类型。这就导致一个函数的声明有时候会看起来十分奇怪:

func (s *Service) register (c *gin.Context)(int, interface{}){
	type registerForm struct{
		UserName 	string
		Password 	string
		Mail 	 	string
	}
	
	var token string
	...
}

这也就是为什么我一上来看 Go 就一脸懵逼的原因。

Gin,好喝!

好像部长和 Hammer 学长都推荐使用 Gin 这个 Go web 框架写后端 API。我便用这个,顺便参照着部长之前写的 CRUD 的 Demo,写的留言板后端。一顿写下来,确实说不出的畅快。畅快到让我感觉这东西封装了太多,而我刚开始入门就用这么简单的框架,不去深入了解 Go 的一些原生语法、实现会不会不太好。但真的是 Gin 写 API 一时爽,一直用 Gin 一直爽。 路由的声明很直接,HTTP 方法应有尽有,就不存在 PHP + Nginx 的 DELETE 方法的坑。 并且,直到用了 Gin,我才明白 Go 中那些让人感觉很烦的结构体的好处到底在哪了。 在 Go 中,比如我要获取一个 POST 过来的 JSON 数据。我需要先声明一个和发送过来的 JSON 数据一样的结构体。 比如,发送过来的 JSON 是:

{
	"UserName": "E99p1ant",
	"Password": "123456"
}

那我在 Go 中,就需要声明一个如下的结构体:

type userForm struct{
	UserName string
	Password string
}

因为 Go 是强类型语言,所以我们不得不在这里声明结构体中元素的类型。 之后我们需要用 Gin 里面的BindJSON()ShouldBindJSON()方法来将传入的 JSON 绑定到一个结构体的实例上:

input := new(userForm)
err := c.ShouldBindJSON(input)

然后他的妙处就体现了,我们只需要判断这个err是否是nil,就可以做到检查 JSON 的入参是否有问题!!(但是我这样写好像并不能判断传入的参数是否为空,我现在是自己再用if判断,看 Gin 的文档中,好像有别的方法可以解决。

同时,提前声明结构体,表明要传入的数据的值的做法,使得 Go 中的一个 SQL 构造器 GORM,可以在判断到数据表不存在时,根据结构体的数据类型建立数据表。(然而我并不喜欢 GORM,不太习惯他那种方式,还是用 Go 原生的数据库中的预编译查询舒服。(可能是因为习惯了 PHP 的 PDO 吧,嘻嘻

真是很舒服很享受的过程啊

像 Go 这种又是编译型,还经常被用来写 Web,同时又是打包成可执行二进制的,真的是很难得啊。之后就是在服务器上搭好 Drone,把 Go 的自动部署给解决了。顺便再随便用 Vue 撸一个留言板的前端,把留言板放上去。我承认自己真香了,Go 真的是天下第一!!

但是,正妻还是 PHP,Golang 嘛……后宫之一咯~

谢谢老板 Thanks♪(・ω・)ノ


喜欢这篇文章?为什么不打赏一下呢?