链客,专为开发者而生,有问必答!html
此文章来自区块链技术社区,未经容许拒绝转载。golang
转用一门新语言一般是一项大决策,尤为是当你的团队成员中只有一个使用过它时。今年 Stream 团队的主要编程语言从 Python 转向了 Go。本文解释了其背后的九大缘由以及如何作好这一转换。编程
Go的优点json
缘由 1:性能api
Go语言的9大优点和3大缺点服务器
Go 极其地快。其性能与 Java 或 C++类似。在咱们的使用中,Go 通常比 Python 要快 30 倍。如下是 Go 与 Java 之间的基准比较:网络
Go语言的9大优点和3大缺点数据结构
Go语言的9大优点和3大缺点并发
Go语言的9大优点和3大缺点框架
Go语言的9大优点和3大缺点
缘由 2:语言性能很重要
对不少应用来讲,编程语言只是简单充当了其与数据集之间的胶水。语言自己的性能经常无关轻重。
可是 Stream 是一个 API 提供商,服务于世界 500 强以及超过 2 亿的终端用户。数年来咱们已经优化了 Cassandra、PostgreSQL、Redis 等等,然而最终抵达了所使用语言的极限。
Python 很是棒,可是其在序列化/去序列化、排序和聚合中表现欠佳。咱们常常会遇到这样的问题:Cassandra 用时 1ms 检索了数据,Python 却须要 10ms 将其转化成对象。
缘由 3:开发者效率&不要过于创新
看一下绝佳的入门教程《开始学习 Go 语言》(http://howistart.org/posts/go...:
package main
type openWeatherMap struct{}func (w openWeatherMap) temperature(city string) (float64, error) {
resp, err := http.Get("http://api.openweathermap.org/data/2.5/weather?APPID=YOUR_API_KEY&q=" + city)
if err != nil {
return 0, err
}
defer resp.Body.Close()
var d struct {
Main struct { Kelvin float64 `json:"temp"` } `json:"main"`
}
if err := json.NewDecoder(resp.Body).Decode(&d); err != nil {
return 0, err
}
log.Printf("openWeatherMap: %s: %.2f", city, d.Main.Kelvin)
return d.Main.Kelvin, nil}
若是你是一个新手,看到这段代码你并不会感到吃惊。它展现了多种赋值、数据结构、指针、格式化以及内置的 HTTP 库。
当我第一次编程时,我很喜欢使用 Python 的高阶功能。Python 容许你创造性地使用正在编写的代码,好比,你能够:
在代码初始化时,使用 MetaClasses 自行注册类别
置换真假
添加函数到内置函数列表中
经过奇妙的方法重载运算符
毋庸置疑这些代码颇有趣,但也使得在读取其余人的工做时,代码变得难以理解。
Go 强迫你坚持打牢基础,这也就为读取任意代码带来了便利,并能很快搞明白当下发生的事情。
注意:固然如何容易仍是要取决于你的使用案例。若是你要建立一个基本的 CRUD API,我仍是建议你使用 Django + DRF,或者 Rails。
缘由 4:并发性&通道
Go 做为一门语言致力于使事情简单化。它并未引入不少新概念,而是聚焦于打造一门简单的语言,它使用起来异常快速而且简单。其惟一的创新之处是 goroutines 和通道。Goroutines 是 Go 面向线程的轻量级方法,而通道是 goroutines 之间通讯的优先方式。
建立 Goroutines 的成本很低,只需几千个字节的额外内存,正因为此,才使得同时运行数百个甚至数千个 goroutines 成为可能。你能够借助通道实现 goroutines 之间的通讯。Go 运行时间能够表示全部的复杂性。Goroutines 以及基于通道的并发性方法使其很是容易使用全部可用的 CPU 内核,并处理并发的 IO——全部不带有复杂的开发。相较于 Python/Java,在一个 goroutine 上运行一个函数须要最小的样板代码。你只需使用关键词「go」添加函数调用:
package main
import (
"fmt"
"time")func say(s string) {
for i := 0; i < 5; i++ {
time.Sleep(100 * time.Millisecond) fmt.Println(s)
}}func main() {
go say("world")
say("hello")}
Go 的并发性方法很是容易上手,相较于 Node 也颇有趣;在 Node 中,开发者必须密切关注异步代码的处理。
并发性的另外一个优质特性是竞赛检测器,这使其很容易弄清楚异步代码中是否存在竞态条件。下面是一些上手 Go 和通道的很好的资源:
https://gobyexample.com/channels
https://tour.golang.org/concu...
http://guzalexander.com/2013/...
https://www.golang-book.com/b...
https://www.goinggo.net/2014/...
缘由 5:快速的编译时间
当前咱们使用 Go 编写的最大微服务的编译时间只需 6 秒。相较于 Java 和 C++呆滞的编译速度,Go 的快速编译时间是一个主要的效率优点。我热爱击剑,可是当我依然记得代码应该作什么之时,事情已经完成就更好了。
Go语言的9大优点和3大缺点
Go 以前的代码编译
缘由 6:打造团队的能力
首先,最明显的一点是:Go 的开发者远没有 C++和 Java 等旧语言多。据知,有 38% 的开发者了解 Java,19.3% 的开发者了解 C++,只有 4.6% 的开发者知道 Go。GitHub 数据代表了类似的趋势:相较于 Erlang、Scala 和 Elixir,Go 更为流行,可是相较于 Java 和 C++ 就不是了。
幸运的是 Go 很是简单,且易于学习。它只提供了基本功能而没有多余。Go 引入的新概念是「defer」声明,以及内置的带有 goroutines 和通道的并发性管理。正是因为 Go 的简单性,任何的 Python、Elixir、C++、Scala 或者 Java 开发者皆可在一月内组建成一个高效的 Go 团队。
缘由 7:强大的生态系统
对咱们这么大小的团队(大约 20 人)而言,生态系统很重要。若是你须要重作每块功能,那就没法为客户创造收益了。Go 有着强大的工具支持,面向 Redis、RabbitMQ、PostgreSQL、Template parsing、Task scheduling、Expression parsing 和 RocksDB 的稳定的库。
Go 的生态系统相比于 Rust、Elixir 这样的语言有很大的优点。固然,它又略逊于 Java、Python 或 Node 这样的语言,但它很稳定,并且你会发如今不少基础需求上,已经有高质量的文件包可用了。
缘由 8:GOFMT,强制代码格式
Gofmt 是一种强大的命令行功能,内建在 Go 的编译器中来规定代码的格式。从功能上看,它相似于 Python 的 autopep8。格式一致很重要,但实际的格式标准并不老是很是重要。Gofmt 用一种官方的形式规格代码,避免了没必要要的讨论。
缘由 9:gRPC 和 Protocol Buffers
Go 语言对 protocol buffers 和 gRPC 有一流的支持。这两个工具能一块儿友好地工做以构建须要经过 RPC 进行通讯的微服务器(microservices)。咱们只须要写一个清单(manifest)就能定义 RPC 调用发生的状况和参数,而后从该清单将自动生成服务器和客户端代码。这样产生代码不只快速,同时网络占用也很是少。
从相同的清单,咱们能够从不一样的语言生成客户端代码,例如 C++、Java、Python 和 Ruby。所以内部通讯的 RESET 端点不会产生分歧,咱们每次也就须要编写几乎相同的客户端和服务器代码。
使用 Go 语言的缺点
缺点 1:缺乏框架
Go 语言没有一个主要的框架,如 Ruby 的 Rails 框架、Python 的 Django 框架或 PHP 的 Laravel。这是 Go 语言社区激烈讨论的问题,由于许多人认为咱们不该该从使用框架开始。在不少案例状况中确实如此,但若是只是但愿构建一个简单的 CRUD API,那么使用 Django/DJRF、Rails Laravel 或 Phoenix 将简单地多。
缺点 2:错误处理
Go 语言经过函数和预期的调用代码简单地返回错误(或返回调用堆栈)而帮助开发者处理编译报错。虽然这种方法是有效的,但很容易丢失错误发生的范围,所以咱们也很难向用户提供有意义的错误信息。错误包(errors package)能够容许咱们添加返回错误的上下文和堆栈追踪而解决该问题。
另外一个问题是咱们可能会忘记处理报错。诸如 errcheck 和 megacheck 等静态分析工具能够避免出现这些失误。虽然这些解决方案十分有效,但可能并非那么正确的方法。
缺点 3:软件包管理
Go 语言的软件包管理绝对不是完美的。默认状况下,它没有办法制定特定版本的依赖库,也没法建立可复写的 builds。相比之下 Python、Node 和 Ruby 都有更好的软件包管理系统。然而经过正确的工具,Go 语言的软件包管理也能够表现得不错。
咱们可使用 Dep 来管理依赖项,它也能指定特定的软件包版本。除此以外,咱们还可使用一个名为 VirtualGo 的开源工具,它能轻松地管理 Go 语言编写的多个项目。