写点什么

用 Go 语言进行编程的利与弊

  • 2019-05-19
  • 本文字数:3049 字

    阅读完需:约 10 分钟

用Go语言进行编程的利与弊

最近,我们使用 Go 语言编写了一个 API,Go 语言是一种开源编程语言,2009 年由 Google 推出。在使用 Go 进行开发的过程中,我们得到了很多经验和心得,想跟读者们分享,于是便有了本文


在为项目选择编程语言时,我们总是建议,在考虑要使用哪种编程语言进行构建之前,先要了解这个项目将要构建的内容。让产品成为应该如何构建的决定性因素。


下面就是我们在使用 Go 语言进行开发时发现的一些利弊,这些可以帮助你了解 Go 语言是否适合用于构建你的下一个项目。

我们喜欢 Go 语言的地方

近年来,Go 语言的使用量呈爆炸式增长。似乎每个初创公司都将它用于后端系统。开发人员认为它如此广受欢迎,背后的原因有很多。

Go 语言速度非常快

Go 语言是一门非常快速的编程语言。因为 Go 语言是编译成机器码的,因此,它的表现自然会优于那些解释性或具有虚拟运行时的编程语言。Go 程序的编译速度也非常快,并且生成的二进制文件非常小。我们的 API 在短短几秒钟内就编译完毕,生成的可执行文件区区只有 11.5MB 这么小。

易于掌握

与其他语言相比,Go 语言的语法很简单,很容易掌握。你完全可以把 Go 语言的大部分语法记在脑子里,这意味着你并不需要花很多时间来查找东西。Go 语言也非常干净易读。非 Go 语言的程序员,尤其是那些习惯于 C 风格语法的程序员,就可以阅读 Go 程序代码,并且能够理解发生什么事。

静态类型定义语言

Go 语言是一种强大的静态类型定义语言。有基本类型,如 int、byte 和 string。也有结构类型。与任何强类型语言一样,类型系统允许编译器帮助捕获整个类的错误。Go 语言还具有内置的列表和映射类型,而且它们也易于使用。

接口类型

Go 语言有接口类型,任何结构都可以简单地通过实现接口的方法来满足接口。这允许你解耦代码中的依赖项。然后,你可以在测试中模拟你的依赖项。通过使用接口,你可以编写更加模块化的可测试代码。Go 语言还具有头等函数,这使得开发人员以更实用的方式编写代码成为可能。

标准库

Go 语言有一个相当不错的标准库。它提供了方便的内置函数,用于处理基本类型。有些包可以让你轻松构建一个 Web 服务器、处理 I/O、使用加密技术以及操作原始字节。标准库提供的 JSON 序列化和反序列化非常简单。通过使用“tags”,你可以在 struct 字段旁边指定 JSON 字段名。

测试支持

测试支持内置在标准库中,不需要额外的依赖。如果你有个名为 thing.go 的文件,请在另一个名为 thing_test.go 的文件中编写测试,并运行“go test”。Go 就将快速执行这些测试。

静态分析工具

Go 语言的静态分析工具众多且强大。一种特别的工具是 gofmt,它根据 Go 的建议风格对代码进行格式化。这可以规范项目的许多意见,让团队奖经理集中在代码所做的工作上。我们对每个构建运行 gofmt、golint 和 vet,如果发现任何警告的话,则构建将会失败。

垃圾收集

在设计 Go 语言时,有意将内存管理设计得比 C 和 C++ 更容易。动态分配的对象是垃圾收集。Go 语言使指针的使用更加安全,因为它不允许指针运算。还提供了使用值类型的选项。

更容易的并发模型

虽然并发编程从来就不是一件易事,但 Go 语言在并发编程要比其他语言更容易。创建一个名为“goroutine”的轻量级线程,并通过“channel”与它进行通信几乎是非常简单的事情,至于更为复杂的模型,也是有可能能够实现的。

我们不喜欢 Go 语言的地方

正如我们前面讨论过的,Go 语言确实是一门优秀的语言。它有一个干净的语法,执行速度也很快速。它还有很多优点。但是,编程语言的全部并不仅仅是指它的语法。下面是我们遇到的一些问题。

没有泛型

首先,这个问题就像房间里的大象一样,是显而易见而又被忽略的事实。Go 语言没有泛型。对于来自使用 Java 这样的语言的开发者来说,要转向 Go 语言,这是一个需要克服的巨大障碍。这意味着代码的重用级别降低了。虽然 Go 语言有头等函数,但如果编写“map”、“reduce”和“filter”等函数,将这些函数设计为对一种类型的集合进行操作,就不能将这些函数重用于其他不同的类型集合。要解决这一问题有很多方法,但都最终都要涉及到编写更多的代码,如此一来,生产力和可维护性就降低了。

接口是隐式的

虽然有接口这一点很好,但是结构却是隐式地而非显式地实现接口。这点被称为是 Go 语言的优势之一,但我们发现,很难从结构中看出它是否实现了接口。你只能通过尝试编译程序才能真正了解。如果程序很小,这当然没有什么问题。但如果这个程序是中大型规模,麻烦就大了。

库支持不佳

Go 语言的库支持参差不齐。我们的 API 与 Contentful 集成,但后者并没有官方支持的 Go SDK。这意味着我们必须编写(并维护!)大量代码来请求和解析 Contentful 中的数据。我们还必须依赖第三方的 Elasticsearch 库。由厂商提供的 Go SDK 并不像他们的 Java、Ruby 或 JavaScript 同类产品那样受欢迎。

社区沟通很难

Go 社区可能不会接受建议。在 golint 的 GitHub 存储库中考虑这个问题:https://github.com/golang/lint/issues/65 ,有用户请求 golint 在发现警告时,能够使构建失败(这就是我们在项目中所做的事情)。维护者立即否定了这一想法。但是,由于有太多的人就这个问题发表了评论,一年后,维护者最终不得不增加了所请求的特性。


Go 社区似乎也不喜欢 Web 框架。虽然 Go 语言的 HTTP 库涵盖了很多方面,但它并不支持路径参数、输入检查和验证,也不支持 Web 应用程序中常见的横切关注点。Ruby 开发人员有 Rails,Java 开发人员有 Spring MVC,Python 开发者有 Django。但许多 Go 开发人员选择了避免使用框架。然而现实是,并非没有框架,恰恰相反有很多。但是,一旦你开始将某个框架用于某个项目,要想避免被遗弃的命运几乎是不可能的。

分裂的依赖关系管理

很长一段时间以来,Go 语言没有一个稳定的、正式的包管理器。经过多年的社区乞求,Go 项目最近才发布 godep。在此之前,已经有许多工具填补了这个空白。我们在项目中使用了非常强大的 govendor,但这意味着社区是分裂的,对刚接触 Go 语言的开发人员来说,这可能是非常令人困惑的。此外,几乎所有的包管理器都由 Git 存储库提供支持,Git 存储库的历史可能随时会发生更改。将其与 Maven Central 相比,后者永远不会删除或更改项目所依赖的库。

决定是否使用 Go 语言

有时候,你需要考虑一下机器的情况。你发送和接受字节时。你管理数千个并发进程时。你也有可能正在编写操作系统、容器系统或区块链节点。在这些情况下,很可能你不会关心泛型。因为你忙着从芯片榨取每纳秒的性能。


但是,很多时候,你需要考虑人类。你需要处理的业务领域数据:客户、员工、产品、订单。你需要编写对这些域实体进行操作的业务逻辑,并且需要多年来维护此业务逻辑。并且需要处理不断变化的需求,还要做的越快越好。对于这些情况,开发人员的经验很重要。


Go 语言是一种编程语言,它更重视的是机器时间而不是人类时间。有时候,你的领域中,机器,或者程序性能是最关键的。在这些情况下,Go 可以成为一个很好的 C 或 C++ 替代品。但是,当你编写一个典型的 n 层应用程序时,性能瓶颈通常会出现在数据库中,更重要的是,你将如何对数据建模。


在决定是否使用 Go 语言时,请考虑以下经验法则:


如果你处理的是字节,那么 Go 语言可能是一个不错的选择。


如果你处理的是数据,那么 Go 语言可能不是一个好的选择。


这种情况也许在未来有一天会改变。Go 语言和社区仍然还很年轻。他们可能会给我们带来惊喜,并添加泛型;或者一个流行的 Web 框架会大获全胜。不过,目前我们将坚持使用成熟的编程语言,这些语言具有普遍的支持、成熟的依赖性管理,并专注于业务领域建模。



2019-05-19 14:0717087
用户头像

发布了 540 篇内容, 共 292.5 次阅读, 收获喜欢 1572 次。

关注

评论 4 条评论

发布
用户头像
在考虑要使用哪种编程语言进行构建之前,先要了解这个项目将要构建的内容。让产品成为应该如何构建的决定性因素。
2021-12-12 11:59
回复
用户头像
新版本 golang,上述部份不足已有支援了
2019-05-27 16:25
回复
用户头像
我在学习go语言时发现go get命令没有进度显示,然后从github上的issue搜索到了好多个对于此问题的讨论,但是从讨论结果来看,go社区从最初到现在依然坚持不添加进度反馈,并且将unix哲学奉为至理。go语言对于包的导入一直令我困惑,对于GOPATH、vendor、项目中的包等这些的导入规则我并没有找到一个统一清晰的说明,社区似乎也没有进行统一的梳理
2019-05-27 11:25
回复
用户头像
这个是老文章了,看法有点过时
2019-05-20 10:31
回复
没有更多了
发现更多内容

CopyOnWriteArrayList 源码分析-其它方法

zarmnosaj

5月月更

虚拟机是什么?跟堡垒机有哪些区别?

行云管家

虚拟机 堡垒机

墨天轮访谈 | 阿里云捷熙:AnalyticDB,人人可用的数据分析服务

墨天轮

数据库 阿里云 国产数据库

小程序转App仅需7步

Speedoooo

ide APP开发 小程序转app 前端IDE

王者荣耀商城异地多活架构设计

小虾米

架构师实战营

探密"一学就会,一用就废"的OKR

Bruce Talk

OKR 敏捷 Agile

企业电子文档管理需要注意的点及解决措施

小炮

文档管理

3000帧动画图解MySQL为什么需要binlog、redo log和undo log

CoderW

后端 面试题 Binlog Redo Log MySQL 数据库

IOC思想开窍之路

留乘船

Java spring ioc

SAP UI5 框架的 manifest.json

汪子熙

前端开发 SAP Fiori SAP UI5 5月月更

技术分享| 快对讲调度系统设计概要

anyRTC开发者

音视频 语音通话 调度 视频通话 快对讲

web前端培训Vue3 TypeScript 如何实现useRequest

@零度

Vue 前端开发

“技术商人”溯源考

IT民工大叔

华为 工程师 任正非讲话 商业意识 复合型人才

SREWorks持续交付云原生化: 镜像构建

阿里云大数据AI技术

大数据 运维 云原生

快速上手vs2019

Loken

音视频 5月月更

CC2530 ADC配置步骤

DS小龙哥

5月月更

服务端技术进阶(三)从架构到监控报警,支付系统设计如何步步为营

No Silver Bullet

架构 支付系统 架构设计 5月月更 监控报警

性能优化手记上篇之【原则】&【方法】

鲸品堂

拯救工程师,远程开发C++的四大秘笈|视频教程

OneFlow

c++ 教程分享

大数据培训实时数仓实践以及架构的演进

@零度

数仓 大数据开发

架构的尽头是架构师

IT民工大叔

架构师

纪念左晖:敢为天下先(修订版)

IT民工大叔

产业互联网 数字化转型 企业家精神 左晖

如视技术副总裁杨永林:当传统产业遇到“数字空间”

阿里云弹性计算

视觉计算 数字空间 VR看房

java培训SpringBoot 中的各种参数校验

@零度

JAVA开发 springboot

eBPF 简介

申屠鹏会

ebpf

高校学生请注意:想成为技术大牛,参加这个计划就够了!

科技热闻

校企融合,打造金融科技应用人才高地

非凸科技

校企合作 非凸

浅析数字化转型与产业互联网

IT民工大叔

产业互联网 数字化转型

【linux运维】linux运维会被淘汰吗?会消失在云计算中吗?

行云管家

云计算 IT运维 云运维

没有JDK和Maven,用Docker也能构建Maven工程

程序员欣宸

Java Docker maven 5月月更

中小互联网公司研发效能团队规模、职能划分和优劣势分析

laofo

DevOps cicd 研发效能 持续交付 互联网公司

用Go语言进行编程的利与弊_语言 & 开发_Samuel Jones_InfoQ精选文章