“本文是国内Go语言大中华区首席布道师——许式伟,在QCon2015上海站上的分享。他预测Go语言10年内一定会超过C和java,并且统治这一个10年。

Go语言语法及标准库变化

Go从1.0版本到现在(2015年)已经有三年多的时间,大的版本发布了五个,下面大家一起看看每个大版本分别都改了什么,当然这里不可能把所有的细节都提到,但我认为重要的会提出来。

首先是Go1.1,Go1.0于2012年4月发布,此后基本维持了每半年发布一个新版本的时间间隔。Go1.5比较例外,在Go1.5的拖累下,Go并没有坚持半年发布一个版本的惯例,因为Go1.5的变化非常大。大家如果对Go有所了解,就会知道Go1.5将基础的实现用Go语言重新写了一遍,但之前是用C写的。

Go1.1是Go1.0之后比较大的版本,相对于后面几个版本而言,里面有更多的语法变更。例如,它最重要的功能是支持方法值,如有一个Foo类型,假设里面有个写的方法,我直接定义一个p的变量,就是访问了这个函数,等价于一个闭包、并调用p.Write(),相当于把第一个参数直接通过p绑定了。有点类似闭包,假设N个变量,少了一个就变成了N-1,第一个参数绑定一个就变成了一个新的闭包。这样的好处是,Go里面大量的函数有上下文,p.Write方式非常适合代入上下文,而且是非常优雅的。

区别于方法表达式(*Foo).Write,结果类型为func(p*Foo,b[]byte)(int,error),方法表达式非常简洁,而且容易理解。

另外,Go1.1的改进还包括int、uint类型长度调整。自Go1.1后,int、uint的尺寸统一是64位(即使在32位平台下)。Go1.1的编译条件也有变化,需要在Go1.1或以上的版本编译。

Go1.1相比后面的版本,除语法变化比较巨大外,还做了很多性能的优化。如:

更多内联,如Append,接类型转换;

全新实现了Map,更小的内存占用和CPU开销;

网络库性能优化,减少了上下文切换;

在标准库/工具上面,Go1.1将一些尚未稳定的库从标准库中移除,迁移到codewww.176yjfg.com

Go1.2语法增加了三下标切片(Three-indexslices):arry[www.176yjfg.com1.2增加了测试覆盖率。

Go1.3,该版本几乎没有语法变化,更多的是实现细节的变化,尤其是GC。最早期的Go被诟病最多的就是GC,这和Go的策略有关系,Go较强调编程范式的稳定。和大家平常做项目一样,需要研发稳定下来的是模块之间的接,语言的编程范式相当于大家交互的接,该接如稳定不下来,对后面的迭代非常有害。所以在Go1.3的版本中,有做大量针对GC的调整,基本上做了小范围的重写。

Go在1.3之前有大量的C代码,所以它的GC其实是经验性的,如果某个整数的值恰巧是一个合法的指针,那么它会被当做一个指针来处理,这样会导致一些内存本来应该释放,当时为了安全不释放,有了这样的经验性,大部分情况已经够用。Go1.3调整为精确GC,这会导致以前的编程手法失效。即如果有人意图把指针存储到uintptr而不是unsafe.pointer,那么这块内存无法保证不被回收;使用unsafe.pointer存储整数也不会是一个好主意,因为这会干扰GC对真相的理解。

在Map的遍历次序上,Go1.3也做了调整,Go1标准指出,对Map的多次遍历不应该假设有同样的次序,为了避免这样的假设发生,Go1.0遍历Map选择起点时用了随机数。Go1.1重新实现Map后,小Map的遍历没有引入随机数,Go1.3重新引入,以消灭此类潜在Bug。

cgo在Go1.3中也有变化,类型不再允许跨包访问。例如,如果某个函数有*C.FILE参数,那么这个函数无法在其他包中使用(会编译失败),如果认为此代码是合理的,可将其调整为unsafe.pointer。

性能方面,Go1.3大大降低了defer的内存开销;引入并行GC算法,大幅改善GC效率;竞争检测算法(racedetector)大幅提速;优化regexp包,改善大部分简单正则表达式的性能。在标准库/工具上,Go1.3新增了debug/plan9obj包。

Go1.4的变化看似很多,但大部分都无关痛痒。它增加了一种非常小概率使用的forrange语法;不再自动对**T进行解引用(dereference);引入internalpackage概念;引入canonicalimportpaths(权威导入路径)概念。实现细节上,它开始支持安卓(编译出binary或.so);运行时(runtime)大部分用Go重写(以前是C),使得GC更加精确,同时,运行时放弃了分段栈(segmentedstack)。

Go1.5在语法上,Map字面量化写法做了变更;实现细节上,它把所有对C的依赖全部消除掉,不需要新的编译器去编Go的代码,只需要用Go的编译器,所以1.5以后编译Go的代码必须用Go,这是一个很重要的变化;GC被重写,进一步降低了GC的latency;GOMAXPROCS默认是调整为CPU数(以前是1);另外,Go1.5开始支持iOS,为此Goteam还提交了第一个Go写的AppStore应用lvy。

Go语言演进回顾

根据Go语言的几个版本,这里总结一下它的演进。

语法变化:几乎没有增加什么明显的语法特性,变化主要围绕:降低心智负担、细节完善、工程化;

Go本身迭代的核心是实现优化,主要围绕:性能、性能、性能!(重要的事情说三遍),性能的优化尤其体现在GC上,此外,还围绕更多的平台移植及更进一步的标准化,以强化社区约定。

Go和Java不一样的地方在于,Go保留了比较大的灵活性的因素。我个人对Go语言未来有这样的判断:Go介于Java和很多灵活性的语言之间。Go的语言特性,三年虽然发布了五个大版本,但其实没有什么语言的实质性变化,我见到有人喷Go时,认为Go语言太不思进取了,也有人认为Go社区对好的想法不思进取、不愿意吸收。

我认为其实不然,不止三年,哪怕是十年,Go语言的语法变化也别指望有大的改进,它基本上只会修补一些很小的地方,我觉得与其说是不思进取,不如说是它对如何写好代码这样的需求理解的自信,这是其他语言远不能企及的,也是我对Go最佩服的地方。

我为什么选Go?并不是因为Go有多好,七牛是做云服务的,云服务特别依赖并行支持,而Go可能是这世界上对并行支持的先行者。

最早七牛用Go的时候,Go1.0还未发布,我当时对语法变化的判断不是特别高,这自信有点类似C,C到现在已经十几年了,但C到现在变过吗?几乎没什么改变,哪怕有C99之类的,变化都很小。Go语言的想法和C很类似,我觉得很难预期Go的语法特性变化很剧烈,但这恰恰是这个语言发展的魅力所在,因为你不用担心你写的代码三十年后会过时。从某种意义上讲,这是一种自信,它已经知道这个世界未来就应该这个样子。

Go语言的研究方向

大家都很关心Go语言未来会如何发展,我觉得三到五年内Go语言的主攻方向仍然是服务端开发,这不会有太大的变化。比如内建HTTP2.0的支持(更多的支持会以独立的开源库的方式提供,未必直接包含在Go的发布包);另外,尽管Go已经开始支持桌面端(Mobile)的开发,但这仍然是探索性和试验性的,如果站在10年的维度上,Go语言会在桌面端(Mobile)大放异彩,占据重要地位。

很有意思的是,全球对Go最感兴趣的是中国,进一步来讲其实是华人,为什么?因为对Go感兴趣排第二的是香港,第三是新加坡,这些地方都是华人聚集地,所以Go语言在中国发展或者在华人圈发展非常不错,比在美国本土还牛很多(当然这仅仅是搜索,其实我是开玩笑的)。从开源项目的角度看,Go在国外发展的其实非常好,刚才所讲的语法特性,大家觉得发展好像很慢,但其实不然,因为它在1.0的时候就把后面的所有做的事情都想好了,后面所要做的就是优化。

下面关于Go,有一些公开的预测:

第一个预测,我最早在2012年新浪微博里提过,Go语言10年内一定会超过C和Java,变成排行榜第一的语言。今天大家可能会略相信,但在2012年的时候没有多少人会相信,即使今天讲出来,绝大部分人都会觉得太早,毕竟它还没有排进前五。

第二个预测,Go语言将在两年内制霸云计算领域。

第三个预测,Go将统治下一个10年。(来自于Deferpanic创始人LanEyberg)。

接下来一个问题,非技术人怎么看Go?第一是国外的投资人怎么看Go,我觉得国外的投资人和中国投资人不一样,他们挺技术范儿的,他们认为“开源的Go语言将成为最持久、最有广泛影响力的开源系统之一”。另外,有商务开发人士认为,“这个世界上好像几乎所有新的、有趣的项目都是用Go写的”。

Go语言开源项目介绍

Go语言的开源项目非常多,而且绝大部分和云计算相关,我这里大致把它分为几类:一类和容器相关,第二类与微服务相关,第三类是数据库类。这三类都是基础设施,以前,大家可能认为基础设施就是操作系统、数据库,但今天的基础设施是什么?数据库和OS依然是,但云服务IaaS、PaaS也是。

大家可以看一下数据库,以前它们都是用C、C++写的(绝大部分最优广泛影响的都是用C写的),但你能想到的数据库并不多。今天,大家能看到的用Go写的数据库有多少?非常多,有键值对的、有时间序列的,还有cockrouchdb(名为小强,因为无论发生什么情况,它都不会死)等。

所以,我们今天看到,基础设施的定义已经发生了变化,实现基础设施最好的方式也发生了变化,不再是以前大家所认为的那样,系统级的东西一定是C开发的,而今天绝大部分新兴的云基础设施(甚至可以认为几乎全部都是)都是Go语言开发的。

那么,Go语言到底发展的怎么样?从Go对自己的定位来讲,它一直关注在服务端开发,服务端开发和今天的主题“云计算时代”有着非常密切的关系,Go想成为云计算时代的核心,成为大家最广泛使用的语言,从某种意义上来讲,它已经达到了。

延展阅读(点击标题):

你天天低头写代码,却未必知道什么在驱动软件开发?

在线支付事故频发,风控系统真的靠谱?

前Facebook早期员工:我是如何肉身翻墙,又回国创业的?|大咖说回放

号外!号外!

阿里巴巴CTO王坚加入GTLC,全球技术领导力峰会讲师阵容再添重磅嘉宾!想一睹王坚博士风采吗?想在现场倾听他的技术领袖之道吗?就在8月GTLC全球技术领导力峰会!

点击阅读原文或扫描二维码进入GTLC官网,截止6月19日前购票,可享受7折特惠票价,此外还有双重半价优惠,更多信息,详见GTLC官网。

本文系InfoQ原创首发,未经授权谢绝转载。

原始网络:http://www.176yjfg.com/archiver/tid-2713.html Go将统治下一个10年?Go语言发展现状分析

Go将统治下一个10年?Go语言发展现状分析的更多相关文章

  1. 【网络】高性能网络编程--下一个10年,是时候考虑C10M并发问题了

    转载:http://www.52im.net/thread-568-1-1.html 1.前言 在本系列文章的上篇中我们回顾了过云的10年里,高性能网络编程领域著名的C10K问题及其成功的解决方案(上 ...

  2. 【原创】高性能网络编程(二):上一个10年,著名的C10K并发连接问题

    1.前言 对于高性能即时通讯技术(或者说互联网编程)比较关注的开发者,对C10K问题(即单机1万个并发连接问题)应该都有所了解."C10K"概念最早由Dan Kegel发布于其个人 ...

  3. 【剑指Offer学习】【面试题58:二叉树的下一个结点】

    题目:给定一棵二叉树和当中的一个结点.怎样找出中序遍历顺序的下一个结点?树中的结点除了有两个分别指向左右子结点的指针以外,另一个指向父节点的指针. 解题思路 假设一个结点有右子树.那么它的下一个结点就 ...

  4. 剑指offer 面试题8:二叉树的下一个节点

    题目:给定一棵二叉树和其中一个节点,如何找出中序遍历序列的下一个节点?树中的节点除了有两个分别指向左.右节点的指针,还有一个节点指向父节点的指针. 中序遍历序列是{d,b,h,e,i,a,f,c,g} ...

  5. SQL Server获取下一个编码字符实现继续重构与增强

        我在SQL Server获取下一个编码字符实现的博文中,虽然实现了这个问题,但是感觉维护起来比较麻烦,例如如果调整编码字符串的固定长度,就需要变更三个函数,这样的为何成本确实比较大.面向对象编 ...

  6. js获取上一个月、下一个月格式为yyyy-mm-dd的日期

    /** * 获取上一个月 * * @date 格式为yyyy-mm-dd的日期,如:2014-01-25 */ function getPreMonth(date) { var arr = date. ...

  7. 从混战到三足鼎立,外卖O2O下一个谁先出局?

    来自第三方数据挖掘和分析机构权威iiMedia Research(艾媒咨询)发布的<2016Q3中国在线餐饮外卖市场专题研究报告>显示,2016Q3中国在线餐饮外卖市场活跃用户分布方面,美 ...

  8. SQL Server获取下一个编码字符实现

    周末看到SQL Server 大V潇湘隐者的获取下一个编码字符串问题,本来作为以上博文的回复,也许回复内容长度超过其允许限制,无法提交.鉴于此,特记录SQL Server实现过程,方便自己回顾和查阅. ...

  9. 引爆公式让你的APP游戏成为下一个“爆款”

    在2014年的移动互联网领域,“魔漫相机”是一款值得关注的产品.虽然没有腾讯.百度或阿里巴巴等大资源的支持,但是这款应用一上线就在中国市场发展迅猛,日下载量超过80万次,最高一日达300万次.类似的成 ...

随机推荐

  1. 使用cordova network-information 插件监听手机网络状态

    在使用html5配合cordova做webapp时,有时需要实时监测手机的网络 状况.html5里面是没有相关的js的,这时就需要在cordova里找相关插件了. 一.插件查找 1.在cordova中 ...

  2. 线段树区间合并——cf1217E

    /* 定义:多重集s的元素和是sum,对于sum的第i位为x,如果s里找不到第i位也是x的元素,那么称这个多重集为bad, 现在给定一个 序列a 两种操作 1 i x:将序列第i个元素改为x 2 l ...

  3. word文档操作

    1.如何把word文档修改的地方标记出来   :  https://zhidao.baidu.com/question/73648149.html 2.word 的几种 视图:https://zhid ...

  4. 学习MFC创建界面

    原始学习文章地址: http://blog.csdn.net/chenyusiyuan/article/details/4744097 一.创建MFC 首先创建一个MFC对话框应用程序(Dialog- ...

  5. 拾遗:ssh 公钥连接前的相关准备

    ssh 公钥连接条件: sshd_config 中启用公钥认证 authorized_keys 文件权限必须为 0600 目标用户的 家目录 权限必须为 0700 目标账户必须已设定登陆密码(即处于可 ...

  6. Python 操作excel常见异常

    一.使用xlrd模块读取excel: 1.报错:IndexError: list index out of range,如下图 解决方法:reading_sheet.cell(1,0).value中c ...

  7. 20140702 赋值构造函数的形参为什么一定用引用。string类的赋值运算函数的注意点

    1.复制构造函数为什么一定要用引用,而不是用值 类名::复制构造函数(类名&引用名) 传递引用,可以避免复制,如果一个数据相当大的化,进行复制会浪费很多时间的. 类名::复制构造函数(类名 变 ...

  8. struts基础

    六个基本包 struts2-core-2.1.6.jar :开发的核心类库 freemarker-2.3.13.jar :struts2的UI标签的模板使用freemarker编写 commons-l ...

  9. ThinkPHP5实用的数据库操作方法

    1.update方法总结 /** * 设置记录的某个字段值 * 支持使用数据库字段和方法 * @access public * @param string|array $field 字段名 * @pa ...

  10. 如何去实现一个运用于多平台的SDK ?

    开始要求实现一个SDk的时候,一脸懵逼,以前总是调别人的SDK暴露的接口与方法,现在自己去实现一个,可以用到各平台上,还是相当有难度的,经过大半月的研究还是有点眉目的,想在这里和大家分享一下鄙人简陋的 ...