NVIDIA 初创加速计划,免费加速您的创业启动 了解详情
写点什么

用 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 框架会大获全胜。不过,目前我们将坚持使用成熟的编程语言,这些语言具有普遍的支持、成熟的依赖性管理,并专注于业务领域建模。



公众号推荐:

跳进 AI 的奇妙世界,一起探索未来工作的新风貌!想要深入了解 AI 如何成为产业创新的新引擎?好奇哪些城市正成为 AI 人才的新磁场?《中国生成式 AI 开发者洞察 2024》由 InfoQ 研究中心精心打造,为你深度解锁生成式 AI 领域的最新开发者动态。无论你是资深研发者,还是对生成式 AI 充满好奇的新手,这份报告都是你不可错过的知识宝典。欢迎大家扫码关注「AI前线」公众号,回复「开发者洞察」领取。

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

发布了 526 篇内容, 共 241.3 次阅读, 收获喜欢 1544 次。

关注

评论 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
回复
没有更多了
发现更多内容

期权的初步认识

Qien Z.

期权 6月日更

什么是 API

escray

学习 极客时间 朱赟的技术管理课 6月日更

你真的会设置密码吗?

卢卡多多

密码学 6月日更

云图说|初识华为云数据库GaussDB(for openGauss)

华为云开发者联盟

数据库 开源 GaussDB GaussDB(for openGauss) 华为云数据库

优秀的 Scrum Master 应当是仆人式的领导

万事ONES

Scrum 敏捷开发 ScrumMaster ONES

让区块链价值的属性之一“免信任”,更好的融入

CECBC

图论环境配置出现的各种错误

容光

【Vue2.x 源码学习】第十六篇 - 生成 render 函数 - 代码拼接

Brave

源码 vue2 6月日更

负载均衡算法之二 - 以 Golang 方式

hedzr

Go 语言 load-balancing weighted random weighted versioning

最牛的编码套路

hasWhere

150亿美元,CANVA可画市场价值为何堪比金蝶、用友?

ToB行业头条

SaaS 可画 品牌视觉管理

「SQL数据分析系列」5. 多表查询

数据与智能

数据库 sql 查询语句

SpringBoot之ScopedProxyMode

梦倚栏杆

区块链场景化应用大有可为

CECBC

烹饪一道美味的 CLI

蛋先生DX

node,js command 6月日更

Redis响应延时问题排查

hasWhere

我想挑战下我的软肋,动手实现个Spring应用上下文!

小傅哥

spring 应用上下文 资源加载 自动识别 扩展机制

【Flutter 专题】102 何为 Flutter RenderObjects ?

阿策小和尚

Flutter 小菜 0 基础学习 Flutter Android 小菜鸟 6月日更

项目进度管理 | 如何为项目制定里程碑?

万事ONES

项目管理 研发管理 研发管理工具 ONES

盘点用jQuery框架实现“for循环”的四种方式!

华为云开发者联盟

jquery 遍历 js 框架 for循环

短链接生成算法

Skysper

算法

react源码解析14.手写hooks

全栈潇晨

React

EasyRecovery---U盘数据恢复技巧

淋雨

数据恢复 EasyRecovery 文件恢复

商用RTC vs 基于开源WebRTC自研 开发者该如何选择?

融云 RongCloud

【融云技术】Native C/C++ 服务适配多指令集 CPU 漫谈

融云 RongCloud

CSS实战 | 磁性页头和页脚的表格制作

devpoint

CSS 6月日更

网络攻防学习笔记 Day46

穿过生命散发芬芳

网络攻防 6月日更

深入了解Spring框架之WebMVC框架

邱学喆

spring webmvc HandlerMethod HandlerInterceptor

WinRM 如何设置 TrustedHosts

HoneyMoose

还不会JVM调优吗?照着做就行

看山

Java JVM 6月日更

清晰理解红黑树的演变---红黑的含义

hasWhere

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