Golang-Go语言关键特性Channel、Goroutine、HTTP Server

一、前言

大名鼎鼎的Docker,完全用GO实现,业界最为火爆的容器编排管理系统kubernetes,完全用GO实现,之后的Docker Swarm,完全用GO实现。除此之外,还有各种有名的项目如etcd/consul/flannel等等,均使用GO实现。有人说,GO语言之所以出名,是赶上了云时代,但为什么不能换种说法,也是GO语言促使了云的发展?

除了云项目外,还有像今日头条、UBER这样的公司,他们也使用GO语言对自己的业务进行了彻底的重构。

Go语言是静态化和编译的语言,这意味着它的运行速度是Python的数倍,而与Python不同的是,Go不需要借助其他语言就可以达到一个较快的速度。Go几乎和C++、Java一样快,而且Go语言的代码编译速度比C++、Java快得多。

GO语言之所以厉害,是因为它在服务端的开发中,总能抓住程序员的痛点,以最直接、简单、高效、稳定的方式来解决问题。这里我们并不会深入讨论GO语言的具体语法,只会将语言中关键的、对简化编程具有重要意义的方面介绍给大家。

二、Go语言关键特性

  • 并发与协程—>goroutine
  • 基于消息传递的通信方式—> channel
  • 丰富实用的内置数据类型
  • 函数多返回值
  • defer机制
  • 反射(reflect)
  • 高性能HTTP Server
  • 工程管理
  • 编程规范

1、并发与协程(goroutine)

并发是Go语言只要优势之一,通过关键字go,语言级别支持协程(微线程)并发,Goroutine是可以同时独立运行的函数,只占2KB内存。

Golang-Go语言关键特性Channel、Goroutine、HTTP Server_第1张图片

很多语言都支持多线程、多进程编程,但遗憾的是,实现和控制起来并不是那么令人感觉轻松和愉悦。Golang不同的是,语言级别支持协程(goroutine)并发(协程又称微线程,比线程更轻量、开销更小,性能更高),操作起来非常简单,语言级别提供关键字(go)用于启动协程,并且在同一台机器上可以启动成千上万个协程。

对比JAVA的多线程和GO的协程实现,明显更直接、简单。这就是GO的魅力所在,以简单、高效的方式解决问题,关键字go,或许就是GO语言最重要的标志。

2、消息通信-channel

channel是Go在语言级别提供给进程内的协程间通信方式,线程安全。

Golang-Go语言关键特性Channel、Goroutine、HTTP Server_第2张图片

在异步的并发编程过程中,只能方便、快速的启动协程还不够。协程之间的消息通信,也是非常重要的一环,否则,各个协程就会成为脱缰的野马而无法控制。在GO语言中,使用基于消息传递的通信方式(而不是大多数语言所使用的基于共享内存的通信方式)进行协程间通信,并且将消息管道(channel)作为基本的数据类型,使用类型关键字(chan)进行定义,并发操作时线程安全。这点在语言的实现上,也具有革命性。可见,GO语言本身并非简单得没有底线,恰恰他们会将最实用、最有利于解决问题的能力,以最简单、直接的形式提供给用户。

Channel并不仅仅只是用于简单的消息通信,还可以引申出很多非常实用,而实现起来又非常方便的功能。比如,实现TCP连接池、限流等等,而这些在其它语言中实现起来并不轻松,但GO语言可以轻易做到。

3、丰富的内置数据类型

Golang-Go语言关键特性Channel、Goroutine、HTTP Server_第3张图片

将错误类型(error)作为基本的数据类型,并且在语言级别不再支持try…catch的用法,这应该算是一个非常大胆的革命性创举,也难怪很多人吐槽GO语言不伦不类。但是跳出传统的观念,GO的开发者认为在编程过程中,要保证程序的健壮性和稳定性,对异常的精确化处理是非常重要的,只有在每一个逻辑处理完成后,明确的告知上层调用,是否有异常,并由上层调用明确、及时的对异常进行处理,这样才可以高程度的保证程序的健壮性和稳定性。虽然这样做会在编程过程中出现大量的对error结果的判断,但是这无疑也增强了开发者对异常处理的警惕度。而实践证明,只要严格按GO推荐的风格编码,想写出不健壮的代码,都很难。当然,前提是你不排斥它,认可它。

4、函数多返回值

Golang-Go语言关键特性Channel、Goroutine、HTTP Server_第4张图片

语言中支持函数多返回值,并不是什么新鲜事,Python就是其中之一。允许函数返回多个值,在某些场景下,可以有效的简化编程。GO语言推荐的编程风格,是函数返回的最后一个参数为error类型(只要逻辑体中可能出现异常),这样,在语言级别支持多返回值,就很有必要了

5、defer延迟处理机制

Golang-Go语言关键特性Channel、Goroutine、HTTP Server_第5张图片

在GO语言中,提供关键字defer,可以通过该关键字指定需要延迟执行的逻辑体,即在函数体return前或出现panic时执行。这种机制非常适合善后逻辑处理,比如可以尽早避免可能出现的资源泄漏问题。

可以说,defer是继goroutine和channel之后的另一个非常重要、实用的语言特性,对defer的引入,在很大程度上可以简化编程,并且在语言描述上显得更为自然,极大的增强了代码的可读性。

6、反射-reflect

Golang-Go语言关键特性Channel、Goroutine、HTTP Server_第6张图片

Golang作为强类型的编译型语言,灵活性上自然不如解析型语言。比如像PHP,弱类型,并且可以直接对一个字符串变量的内容进行new操作,而在编译型语言中,这显然不太可能。但是,Golang提供了Any类型(interface{})和强大的类型反射(reflect)能力,二者相结合,开发的灵活性上已经很接近解析型语言。在逻辑的动态调用方面,实现起来仍然非常简单。既然如此,那么像PHP这种解析型语言相比于GO,优势在那里呢?就我个人而言,写了近10年的PHP,实现过开发框架、基础类库以及各种公共组件,虽然执行性能不足,但是开发效率有余;而当遇上Golang,这些优势似乎不那么明显了。

7、高性能HTTP Server

Golang-Go语言关键特性Channel、Goroutine、HTTP Server_第7张图片

作为出现在互联网时代的服务端语言,面向用户服务的能力必不可少。GO在语言级别自带HTTP/TCP/UDP高性能服务器,基于协程并发,为业务开发提供最直接有效的能力支持。要在GO语言中实现一个高性能的HTTP Server,只需要几行代码即可完成,非常简单。

8、工程管理

Golang-Go语言关键特性Channel、Goroutine、HTTP Server_第8张图片

在GO语言中,有一套标准的工程管理规范,只要按照这个规范进行项目开发,之后的事情(比如包管理、编译等等)都将变得非常的简单。

在GO项目下,存在两个关键目录,一个是src目录,用于存放所有的.go源码文件;一个是bin目录,用于存在编译后的二进制文件。在src目录下,除了main主包所在的目录外,其它所有的目录名称与直接目录下所对应的包名保持对应,否则编译无法通过。这样,GO编译器就可以从main包所在的目录开始,完全使用目录结构和包名来推导工程结构以及构建顺序,避免像C++一样,引入一个额外的Makefile文件。

在GO的编译过程中,我们唯一要做的就是将GO项目路径赋值给一个叫GOPATH的环境变量,让编译器知道将要编译的GO项目所在的位置。然后进入bin目录下,执行go build {主包所在的目录名},即可秒级完成工程编译。编译后的二进制文件,可以推到同类OS上直接运行,没有任何环境依赖

9、编程规范

Golang-Go语言关键特性Channel、Goroutine、HTTP Server_第9张图片

GO语言的编程规范强制集成在语言中,比如明确规定花括号摆放位置,强制要求一行一句,不允许导入没有使用的包,不允许定义没有使用的变量,提供gofmt工具强制格式化代码等等。奇怪的是,这些也引起了很多程序员的不满,有人发表GO语言的XX条罪状,里面就不乏对编程规范的指责。要知道,从工程管理的角度,任何一个开发团队都会对特定语言制定特定的编程规范,特别像Google这样的公司,更是如此。GO的设计者们认为,与其将规范写在文档里,还不如强制集成在语言里,这样更直接,更有利用团队协作和工程管理。

你可能感兴趣的:(Go,go)