Go语言学习一——出身名门

Posted 自由水鸟

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Go语言学习一——出身名门相关的知识,希望对你有一定的参考价值。

毫无疑问,在编程语言领域,Go正在成为一颗冉冉上升的新星。由于它在执行性能与开发效率方面都非常出色,正在被越来越多的公司所采用,国外的大公司如Google、Facebook等就不说了,国内的今日头条、滴滴、小米、七牛云等都在积极尝试。

Go的火热不仅体现在传统互联网应用中,在新兴的区块链领域中也有大量应用,例如以太坊智能合约框架以及商业区块链框架实现Fabric都使用了Go语言。

今天我们就来一起认识一下这位编程语言业界的后起之秀。

一. 诞生

Go语言诞生于Google,且它的作者各个都是神一样的人物:

  • 肯·汤普逊(Ken Thompson,http://en.wikipedia.org/wiki/Ken_Thompson):设计了B语言和C语言,创建了Unix和Plan 9操作系统,1983年图灵奖得主,Go语言的共同作者。

  • 罗布·派克(Rob Pike,http://en.wikipedia.org/wiki/Rob_Pike):Unix小组的成员,参与Plan9和Inferno操作系统,参与 Limbo和Go语言的研发,《Unix编程环境》作者之一。

  • 罗伯特·格里泽默(Robert Griesemer):曾协助制作Java的HotSpot编译器和Chrome浏览器的javascript引擎V8。

  • 布拉德·菲茨帕特里克(Brad Fitzpatrick,http://en.wikipedia.org/wiki/Brad_Fitzpatrick):LiveJournal的创始人,著名开源项目memcached的作者。

而且,他们大部分都来自于曾诞生了无数计算机科技成果的贝尔实验室,后来加入了Google。上面介绍中的Plan9就是他们之前在贝尔实验室的项目,而Limbo语言则是Plan9项目衍生出来的,之后成为了Go语言的前身。

时间回到2007年,那时候Go语言还是上面这帮大佬们在Google闲暇时消遣的一个实验项目。他们中的很多人是C语言的作者,C语言虽然在很多底层实现中依然有着无可替代的作用,但是C语言毕竟是诞生于上世纪70年代,在21世纪互联网蓬勃发展的今天,C语言并不适合于互联网应用。因此,他们萌生了要开发一款互联网时代的C语言的想法。

2009年,Google发布了Go语言的第一个非正式版本,2012年发布了正式版,截止到2018年5月,已经升级到1.10.2版本了。

不夸张的说,如果说从2007年诞生到今天已经11岁的Go语言是一个意气风发的少年的话,他出身名门,有着C语言和众多现代语言的优良基因,从一开始就备受瞩目,而今正在大步向前!

二. 设计思想

Go语言的设计目标是要提供互联网时代的编程语言,那么相比传统的单机应用就要解决如下问题(相对于C语言而言):

  • 并发:C语言虽然也可以提供并发支持,但使用成本较高,今天但网络应用很多都对高并发有着更高对要求,而且服务器核心数越来越多

  • 大规模分工协作:C语言是一门面向过程的语言,在开发大规模应用时不尽如人意,依赖管理是一件让人头疼的事

  • 编程效率:C语言的优势是执行效率,但是开发效率却很低,C++和Java等面向对象语言也显得过于笨重

  • 垃圾回收:C语言需要自己管理内存,这是一个门槛很高的技术活儿,很多高级语言如Java早就提供了垃圾回收的完整方案

Go语言期望达到的目标是:

  • 原生支持多核计算核并发

  • 简单高效的依赖管理,快速编译和构建

  • 提升开发效率

  • 提供垃圾回收等程序员友好等特性

在实现上述目标的同时,Go语言有一个明显的设计原则就是:凡是可能带来困扰又不是特别必要的特性,那就不提供;凡是经常用到的重要特性,提供简单易用的实现方式。换句话说:对于新特性的新增极为克制,对于常用功能的实现追求极致!

以下试举几例:

  • Go语言不提供方法重载:方法重载虽然看起来让程序员更好的命名和管理方法,避免出现过多的方法名,但同时也会给编译和链接带来额外的开销,不提供方法重载反而简单一些,于是Go语言就把这个特性干掉了

  • 一个关键字即可启动一个新的线程:go xxx

  • 强制代码书写规范,例如{的位置,只能有一种写法,这可以从很大程度上确保代码规范,提高可读性

在Go官方的文档中关于Go语言为什么不提供这样那样的特性,有这样一个有意思的说明,或许可以直观的感受Go语言的设计思想:

Every language contains novel features and omits someone's favorite feature. Go was designed with an eye on felicity of programming, speed of compilation, orthogonality of concepts, and the need to support features such as concurrency and garbage collection. Your favorite feature may be missing because it doesn't fit, because it affects compilation speed or clarity of design, or because it would make the fundamental system model too difficult. If it bothers you that Go is missing feature X, please forgive us and investigate the features that Go does have. You might find that they compensate in interesting ways for the lack of X.

三. 核心特性

废话不多说,直接上干货:

自动垃圾回收

C和C++灵活的指针和内存控制让程序员可以任意挥洒,感受自由与奔放,彷佛世界尽在掌握,在程序世界里,你就是上帝,掌握着所有对象的生杀予夺!但这往往也意味着安全隐患,内存泄漏的魔爪随着准备着伸向我们脆弱的程序。

Java等提供垃圾回收特性的语言可以说彻底的解放了程序员,从此程序员写代码就像是进了五星级大饭店,想吃什么直接拿就是,吃完饭拍拍屁股走人就是,那些擦桌子洗碗的活儿就交给服务员吧。

有着远大理想的Go语言自然会为程序员提供如此高级的服务了。

函数多返回值

大多数编程语言的函数都只支持返回一个值,如果有返回多个值的情况,通常有两种做法:

  1. 返回一个对象

  2. 函数的参数中传递返回值的指针,并在函数中赋值

以上哪一种方法其实都算不上优雅,而Go语言直接支持了返回多个值,像下面这样:

ip, port := getServerInfo()

匿名函数和闭包

匿名函数和闭包都是动态语言如Javascript,php中的特性,可以在一定场景下提供更灵活的表达,提高开发效率。Go对这两者也提供了很好的支持。

无层级的类型系统

我们都知道在C++和Java等面向对象语言中都支持类继承,这就会形成一个类的关系树,如下图所示:

而在Go语言中,是不支持显示继承的,也就是说没有java中的extendsimplement关键字。但这不意味着Go语言中就无法实现面向对象的继承,只是说Go换了一种更灵活的方式,也就是非侵入式继承,简单来说就是没有明显的类层级,同样实现上面的功能,只需要如下声明即可:

Go语言学习一——出身名门

只要Dog和Cat实现了Animal类中的方法,那么Go就认为他们是有一定亲缘关系的,那么就可以实现如下写法:

type Animal interface {
   eat()
}

type Cat struct {

}

func (c *Cat) eat() {
   fmt.Println("cat eat")
}

func main() {
   var animal Animal = new(Cat)
   animal.eat()
}

这样做的好处主要有以下几点:

  • 接口与类的关系是松散的,而不是强绑定的,只要某个类实现类接口的所有方法,那么这个类实际上就实现了这个接口,会带来一定的灵活性

  • 使程序员更关注与业务实现,不用花太多时间在接口设计上,甚至可以先实现业务类,再根据需要声明一个合适的接口

并发

Go语言中引入了一个概念叫做goroutine,或者叫协程,它是一种比线程更加轻量级的并发单元,只需要使用go关键字一行代码就可以启动协程。也因此,Go语言在高并发处理方面表现十分优异。有一篇来自国外的关于并发性能的对比,虽然未必能反应Go全部的实力,但是还是可以在某种程度上看出Go的并发性能优势:每个线程执行一次哈希运算,5000并发下的不同语言的QPS对比如下:

Go语言学习一——出身名门

高性能

Go是一种编译类型的语言,在运行前会被编译链接为一个可执行的二进制文件,执行效率还是很高的,在权威的性能测试中,很多场景的性能是好于Java的,比python更是好了几个数量级:

Go与Java性能对比
Go与Python性能对比

更多对比可以参考这个网站:https://benchmarksgame-team.pages.debian.net/benchmarksgame/faster/go.html

以上就是富二代Go语言的出身介绍了,更多细节,请期待后文。

参考资料

  • 许式伟:《Go语言编程》

  • https://golang.org/doc/faq#overloading

  • https://golang.org/doc/faq#Why_doesnt_Go_have_feature_X

  • https://zhuanlan.zhihu.com/p/22486908?refer=study-fe

  • https://benchmarksgame-team.pages.debian.net/benchmarksgame/faster/go.html

  • https://blog.csdn.net/STFPHP/article/details/72617749


以上是关于Go语言学习一——出身名门的主要内容,如果未能解决你的问题,请参考以下文章

容器编排工具很多套,出身名门的Swarm上不了

drawer的音标和词性

你知道的Go切片扩容机制可能是错的

解决go: go.mod file not found in current directory or any parent directory; see ‘go help modules‘(代码片段

开发你的第一个React + Ant Design网页(一配置+编写主页)

小白学爬虫:开源爬虫框架对比