当前位置: 首页 > 编程日记 > 正文

GO是更好的编程语言吗?

引言

团队有项目考虑用GO重写,所以花了些时间调研GO。
606573-20190619215414981-676820385.png

第一次接触GO是2年前,17年3月份,全职钻研一周,彼时C++中毒太深,内心排斥其他编程语言,看其他语法总觉得有点怪,而且有“C/C++能做任何事,故无用其他语言之必要”的思想在作祟。
606573-20190619215628893-301298971.png

人都有思维定势,受限于自己的经验和认知,我亦不能例外,但好在我意识到这一点,所以在调研过程中,努力摒弃成见,尽量摆脱惯性,查阅关于GO的各种(包括核心设计师)文章,倾听拥趸和批评者的不同声音,结合自己的思考和分析,力求客观公正去评价GO。

GO语言简介

GO是Google开发的一种静态、强类型、编译型、并发型,并具有垃圾回收功能的类C编程语言。2009以开源项目的形式发布,2012年发布1.0稳定版本,距今已经十年了。

发明一种新的编程语言,首先得找到必要性,不然肯定会被质疑重复造轮子,方法嘛?无非是先找某种语言的一些茬,吐槽一番,复杂、笨拙、低效,太TM沙雕了,不能忍,劳资要立刻马上分分钟撸出一种新的编程语言,完美解决所有问题,不然对不起我卓尔不群的智商。
606573-20190619215701854-2136295594.png

GO的故事也很套路,G公司的Pike大牛听完C++0x的演讲,回到办公室,开始编译C++,等待编译过程中,转过椅子面向Robert,讨论语言的问题,然后拉上Ken爷爷一起合计,群嘲之后,受不了C++某些沙雕设计,还没等编译完成,三个老男人便一拍即合,决定一起搞点change the world的伟大事情,于是乎,GO诞生了。

GO语言之父Pike提到:GO语言是以C为原型,以C++为目标而设计的,希望C++程序员能以GO作为替代品。因为他觉得C++忒复杂了,要解救程序员于水火。

虽然GO以C++为目标而设计,但尴尬的是,Pike坦承GO并没有吸引来多少C++程序员,反而是吸引了不少Python、Ruby程序员。这、这、这、这。。。

GO核心团队

G公司不差钱不缺人,GO团队更是群星荟萃、大咖云集,不废话,直接上图:
606573-20190619220051293-1981230760.png

核心设计师Pike和Ken都是出身自贝尔实验室,Ken之于Pike,亦师亦友,共同发明了UTF-8,还基情四射地结对编程过,感情好的穿一条裤子。

Pike是Unix先驱,贝尔实验室最早跟Ken、Dennis一起开发Unix的猛人,Plan9 OS的灵魂人物。大胡子Ken爷爷则是Unix之父,和Dennis一起发明了C语言,殿堂骨灰级程序员,早已是名满天下。

技术实力毋容置疑,不过这哥俩都是玩Kernel的,经历相同,理念相近,分歧会比较少,他们也都坦承C用得最多最熟,所以注定了GO的类C特性,不过这会不会导致GO设计上的思维火花不足,对OOP以及现代编程思想的支持不足,亦未可知。

GO的哲学

哲学是难分对错的,GO有GO的哲学,有它的取舍和审美,不一定每个人都认同,我觉得还挺有道理的,罗列如下:

少即是多

GO信奉Less Is More,大道至简,臆测是乔帮主的信徒。

世界是并行的

世间万物是并行发生的,所以GO遵照这个规律,对并发的原生支持让GO更易于描述并行世界。

世界是物质组成的

微观世界由小的粒子组合成大的粒子;宏观世界由小的物体组合成大的物体。继承只能描述现实世界的一小部分,使用继承是不全面的;GO的设计选择的是组合,这个和现实世界比较吻合的设计,表现力更强。

世界是标准化的

硬件是标准化的,软件也应如此,GO的接口是DUCK模型,接口是非侵入式的。

正交性

GO的多个特性都是正交性的,正交性是保持事物稳定和简单的最好设计。

二八定律

80%代码只使用20%特性,增加语言特性,并不能提升效率,反而会增加复杂性,提高犯错率,加重程序员心智负担。

统一格式化

C++语法自由自在,于是乎一群吊丝为tab or space、大括号要不要换行等诸如此类的格式问题吵得不可开交。GO设计师认为,都是吃饱了撑的,你们太愚蠢了。

于是GO规定左大括号{不能换行放置,没有为什么,对着干直接编译不过。

GO编译器内建工具gofmt强制源码格式化。对不起,没有选项,我的地盘听我的,把精力focus到真正重要的事情上来,停止无意义的争吵。

这其实也是一种哲学:给你(我认为)最好的,而不是给你选择。就像iPhone一样,用户太笨了,他们根本不知道自己需要什么,就让帮主替你安排好一切吧。

不过GO强加个人喜好的一刀切做法,也招致批评和厌恶。有比较刚的程序员,直接因为大括号不让换行而抛弃GO。

作为一个经历过各种妖媚代码格式要求的程序员,我发出了杠铃般的笑声。

GO的特色

GO是介于C与C++之间的语言,比C抽象层次高,比C++抽象层次低。

因为是一门新的编程语言,站在巨人的肩膀,博采众长,规避了一些已知的问题,开发了一些优秀的特征,相比C/C++,GO的核心特征包括以下几个方面:

  1. 原生并发,以东尼·霍尔的通信顺序进程(CSP)为基础的goroutine,适合现代多核机器
  2. 垃圾回收,非常高效(请来世界顶级内存管理专家设计)
  3. 强大的标准库,对网络编程等的良好支持
  4. CGO提供了GO调用C机制,扩展了GO的能力边界
  5. 内嵌关联数组
  6. 非侵入式的接口设计
  7. 简单清晰的语法,以及强编码规则,好处可能远超想象

GO vs C/C++

606573-20190619220122090-2127571598.png

GO与C语法详细对比

性能对比

虽然GO号称兼备C++的运行效率和PHP的开发效率,但benchmarks好像打脸了,从数据上看,GO的运行效率接近却略低于Java
606573-20190619220213722-1683872711.png

研发效率

606573-20190619220232695-1062911197.png

我乐观预计GO的研发效率上优于C/C++,特别是*nix环境下。

流行度

GO获得TIOBE 2016年度最佳,2017年10月获得第10,历史最高排名。
GO诞生10年,虽然背靠Google,但依然没有挺进编程语言第一阵营,属于外围三线。
近一年多流行度排名有所下滑,铁打的Java、C/C++,流水的编程语言。

606573-20190619220544274-2063501618.png

工程化水平

606573-20190619220608795-1218166663.png

知名项目:
Docker:大名鼎鼎的开源应用容器引擎
K8S:容器编排管理系统的事实标准
...

GO更适合开发服务器端大型软件,高性能分布式系统领域,网络编程,并发编程,被誉为云时代的C语言。

GO成为云计算时代流行起来,促进了云计算的发展,Google用GO的多,今日头条、Uber等公司也用GO对业务进行了彻底的重构,golang.org YouTube.com也在使用GO开发。

美国市值TOP20有一半在使用GO,国外很多初创公司选择GO,国内关注高,但还未得到广泛应用,应用上呈现国外热国内冷的特点

Go语言目前所面临的最大问题在于,还没有足够的经验来证明GO是否真的是一个成功的产品,缺少足够多超大型应用的实践。

总体而言,GO的工程化水平低于C/C++和Java等第一梯队语言。

争议和不足

GO最初声称为了解决Google的问题而设计,为了帮助人们阅读、调试和维护软件而生,但目前为止,难言圆满。

GO的异常处理经常被吐槽,GC提高了安全性却失去了控制力,组合代替继承真的好吗?包管理做的好吗?

摒弃先入为主的观念影响,重新客观审视GO语言,我觉得在语言设计层面,GO确实更自然、更简约。比如摒弃行尾的分号,比如if/for不需要圆括号包裹条件,放空内心去想,好像真的更合理。

GO抖掉了C++的诸多包袱,让程序简单,也更容易理解(特别是相对于C),但是随着GO的发展,语法也有可能变重,比如GO 2.0版又把它之前批评的泛型引入了,当初GO批评别人的点又有可能反过来被别人批评。

而关于语法层面是否真的更简洁,也是有争议的,三目运算符不支持+强制大括号让一行C代码变成多行GO真的更简单了吗?比如编程语言专家庄晓立(Liigo)在CSDN上有吐槽的文章,仔细读来,也有一定道理,我贴一个链接,可以参考一下。
原文链接:https://blog.csdn.net/liigo/article/details/23699459

另外GO是G公司的,虽然目前开源,但会不会哪天也像Oracle一样,穷疯了便开始薅羊毛,Oracle Java JDK已经开始割韭菜了,所以GO智慧产权的风险依然存在,而C/C++已经是宇宙人类的了,世界性的标准化组织在控制管理,风险无穷逼近于零。

小结

GO在一些点确实有突破,比如让并发编程更容易、运行更高效,比如垃圾回收让程序更安全,比如基于消息(Channel)编程的支持,比如内嵌关联结构,这些都很赞,也很重要。编程语言发展这么多年,任何突破都是艰难和宝贵的。

Goroutine是GO的杀手锏,经过GO改造后的系统很可能有更高并发量和IO吞吐率。

GO跟C非常像,这并不奇怪,因为设计师都是C/C++语言大师,C/C++程序员很容易切换到GO,但Java程序员转GO可能要困难一些。

另一个隐患就是在Java占主导的生态中,GO显得比较小众,跟其他中间件的融合也存在潜在风险,引入复杂性甚至混乱。

回到标题的问题,GO是更好的语言吗?GO是理想的编程语言吗?说实话,我不知道,而且我的观点也不重要,这似乎是一个哲学问题。

是否要选择GO作为项目开发语言,我认为不应该被GO声称的优势迷惑,因为你去google任何一门语言,都能收获一堆优点,PR会自然而然的对缺点选择性忽视。

但也不能因循守旧,而应该仔细辨别,你度量什么便得到什么。GO是否适合你的项目,GO的新特点和优势对你的项目是否真有必要,是否真有帮助,能给你的项目带来什么好处?比如你写一个单机游戏程序可能GO网络库对项目毫无意义,所得收益跟你付出新学一门语言的成本相比如何?同时,它的缺陷是什么?你是否全面理解?

有时候,它或许就像一位花枝招展的姑娘,待你抛弃一切去拥抱它的时候,你会发现,它的美好只是存在于你的幻想中,当然也有另一种可能,它真的非常好,很适合你,恭喜你,热情的拥抱它吧。

GO有它适应场景,比如适合网络程序、云应用、微服务、高性能分布式、大型多人协同,可能在开发效率上有非常大的提升,清晰度上也有提高,可能是理想的首选。

或许我会尝试用GO开发新项目或者改写老项目,谁知道呢?这取决于权衡折中,取决于领导决断,也取决于我的心情。

附录

一段GO的示例代码,品味一下GO的style。

package mainimport ("fmt""go/ast""go/importer""go/parser""go/token""go/types""log"
)const hello = `package main
import "fmt"
func main() {fmt.Println("Hello, world")
}
`//!+
func PrintDefsUses(fset *token.FileSet, files ...*ast.File) error {conf := types.Config{Importer: importer.Default()}info := &types.Info{Defs: make(map[*ast.Ident]types.Object),Uses: make(map[*ast.Ident]types.Object),}_, err := conf.Check("hello", fset, files, info)if err != nil {return err // type error}for id, obj := range info.Defs {fmt.Printf("%s: %q defines %v\n",fset.Position(id.Pos()), id.Name, obj)}for id, obj := range info.Uses {fmt.Printf("%s: %q uses %v\n",fset.Position(id.Pos()), id.Name, obj)}return nil
}//!-func main() {// Parse one file.fset := token.NewFileSet()f, err := parser.ParseFile(fset, "hello.go", hello, 0)if err != nil {log.Fatal(err) // parse error}if err := PrintDefsUses(fset, f); err != nil {log.Fatal(err) // type error}
}

转载于:https://www.cnblogs.com/crazyacking/p/11057067.html

相关文章:

定位DIV滚动条

如果由于table中有一个下拉框,还有一个treeview时,treeview的所有节点都是取于下拉框的下拉选项来的,所以在第一定位这之后,当选择其他下拉框中其他的选项时,DIV的scrollTop值是会一直保存前一个步聚DIV滚动条所在的位…

JS作用域相关知识(#精)

在学习《你不知道的JS》一书中,特将作用域相关知识在此分享一下: #说到作用域,就不得不提到LHS查询和RHS查询: 1)如果查询目的是对变量进行赋值,则使用LHS查询 2)如果查询目的是获取变量的值,则使用RHS查询 作用域的查询都会从当前…

RUP within the context of the Six Best Practices

前面几期图文介绍了软件工程中常见的问题,以及找到它们的根本原因,提出了在软件工程实践中总结出来的六个最佳工程实践。迭代化开发、需求管理、基于构件的体系结构、可视化建模、持续的质量验证、变更管理。今天我们介绍Rational公司的RUP,看…

排序算法java版,速度排行:冒泡排序、简单选择排序、直接插入排序、折半插入排序、希尔排序、堆排序、归并排序、快速排序...

先推荐一篇关于排序算法的文章:http://www.cppblog.com/guogangj/archive/2009/11/13/100876.html 本文思路部分来源于上篇文章,但测得的结果似乎不大相同,不知是因为java的缘故还是因为我算法的缘故,欢迎拍砖。 复习排序&#xf…

项目存档管理规范

项目存档管理规范 在我们开发过很多个项目之后,每个项目都会累积下很多源码、文档等,查找和整理起来很不方便,如果我们又要同时工作于多个项目的话,情况会更糟。所以对每个项目的各种档案进行有效管理很有必要,从公司层…

review what i studied `date` - 2017-4-12

python 连接字符串 int srt >>> a 1 >>> b xuhui >>> a b Traceback (most recent call last):File "<stdin>", line 1, in <module> TypeError: unsupported operand type(s) for : int and str >>> b str(a)…

StaticFactoryMethod_Level1

以下代码是“简单工厂模式”的第一个例子&#xff1a;

逃离深圳,一个程序员的选择

到新公司上班也已经一个多月了&#xff0c;上周刚刚交了首付&#xff0c;总价50多万&#xff0c;97个平方的房子还外送8个平方。为了不忘记这次的选择&#xff0c;也为了记录这次选择的过程&#xff0c;特撰文如下。 自从得知老婆怀孕后&#xff0c;那是相当高兴&#xff0c;但…

弹出窗口(对话框)

对话框分为三种&#xff1a;window.open方法 无模式对话框 有模式对话框 第一&#xff1a;OPEN方法 <script>functionopen_cate(){ window.open("OpenUp.aspx","","toolbar0,location0,directories0,status0, menubar0,scr…

隐藏系统保留区

为了下午的装机活动自己就安了一个老毛桃&#xff0c;制作启动盘完毕后发现电脑中的“系统保留”盘出来了&#xff0c;为什么会出现这个盘呢&#xff1f; 当笔记本安装Windows7系统时会自己主动产生一个几百兆的系统保留分区。里面保存着系统/磁盘引导的数据。有些笔记本在出厂…

StaticFactoryMethod_Level2

以下代码是“简单工厂模式”的第二个例子&#xff1a;

06- web兼容性测试

稍后更新。。转载于:https://www.cnblogs.com/Chamberlain/p/11064664.html

話說我們家姚明

已經讀三年級了,成績不錯,有目共睹!最近三場比賽連續三次得分在30分以上...呵呵~在NBA那個高手如雲的地方如此出色! ^_^#好強~ 真的好強!!麥迪那個軟蛋,干脆把他賣掉得了!拿高工資不做事的人.. 凸-_-转载于:https://www.cnblogs.com/tohen/archive/2006/03/09/346286.html

20145240《网络对抗》MSF基础应用

MSF基础应用 一个主动攻击&#xff0c;如ms08_067 启动msfsearch ms08_067&#xff0c;查找相应的漏洞&#xff0c;查询可攻击的模块。根据上述漏洞的模块use exploit/windows/smb/ms08_067_netapi选择该模块接下来查看相应的攻击载荷&#xff0c;首先我们可以查看可使用的载荷…

StaticFactoryMethod_Level3

以下代码是“简单工厂模式”的第三个例子&#xff1a;

Dynamics CRM 导入用户数据错误 could not retrieve salesperson role

在CRM中通过导入数据的方式创建用户时报下图中的错误&#xff0c;“could not retrieve saleperson role”。原因是系统中的自带的salesperson安全角色被删除了&#xff0c;在用导入数据的方式导入文档新建用户时是没有安全角色让你选择的&#xff0c;系统默认给分派了销售员的…

也许这样叫做成熟

早上想坐早班车来接三日游回来的佳&#xff0c;不料还是比旅游团的车晚一步&#xff0c;不过今天到……小结&#xff1a;1、做事&#xff0c;大事不糊涂&#xff0c;小事灵活受理&#xff1b;2、目标明确&#xff0c;善始善终&#xff1b;3、卧薪尝胆&#xff0c;体味时间的诅咒…

写文章 TEE技术分析【转】

转自&#xff1a;https://zhuanlan.zhihu.com/p/24222064 首先介绍一下TEE的主要关键技术&#xff1a; 1&#xff0e;安全启动&#xff08;Secure Boot&#xff09; 安全启动技术可以用于需要防止篡改系统镜像&#xff0c;比如安全系统&#xff0c;安全手机镜像等。 2&#xff…

StaticFactoryMethod_Level4

以下代码是“简单工厂模式”的第四个例子&#xff1a;

jquery 获取Select option 选择的Text和Value

jquery radio取值,checkbox取值,select取值,radio选中,checkbox选中,select选中,及其相关设置 获取一组radio被选中项的值:var item $(input[nameitems][checked]).val();获取select被选中项的文本:var item $("select[nameitems] option[selected]").text(); 获取…

Android -- Annotation(注解)原理详解及常见框架应用

1&#xff0c;我们在上一篇讲到了EventBus源码及3.0版本的简单使用&#xff0c;知道了我们3.0版本是使用注解方式标记事件响应方法的&#xff0c;这里我们就有一个疑问了&#xff0c;为什么在一个方法加上类似于“Subscribe”&#xff0c;就可以让我们的反射找到我们的事件响应…

简单工厂模式(StaticFactoryMethod)

来华北电力大学数理系LSGO软件技术团队学习Coding&#xff0c;我通常第一个就讲“简单工厂模式”&#xff0c;这一讲不仅仅是讲模式&#xff0c;更主要的是让大家体会什么是软件系统的“可复用”、“可扩展”、“易维护”、“灵活性好”&#xff0c;以及如何通过面向对象程序设…

Html,Css,Javascript是什么?

本文属于基础科普文&#xff0c;高富帅们请绕道吧。 Html&#xff0c;css&#xff0c;javascript是做网页前台设计的标准套装&#xff0c;html是一些网页控件&#xff0c;css是美化这些控件的代码&#xff08;层叠样式表&#xff09;&#xff0c;js&#xff08;javascript&…

[转帖]ERP术语

栖息谷-IT管理-[转帖]ERP术语 [转帖]ERP术语 1 英文缩写&#xff1a; MIS 英文全称&#xff1a; Management Information System 中文翻译&#xff1a; 管理信息系统 简释&#xff1a; MIS是指对企业大量的原始管理…

how tomcat works 总结 二

第五章 servlet容器 第 5 章讨论 container 模块。container 指的是 org.apache.catalina.Container 接口&#xff0c;有4 种类型的 container:engine, host, context 和 wrapper。这章提供了两个工作于 context 和wrapper 的程序。容器共分四类,类图例如以下:一个wrapper就是一…

策略模式(Strategy)

这是来数理系LSGO软件技术团队学习Coding&#xff0c;第二个要学习的设计模式。该模式在解决同一个问题时可以使用不同的算法。以满足“开闭原则”&#xff0c;把各种算法与实际业务逻辑解耦合&#xff0c;以便写出良好的代码。

[scrum]2011/9/22-----第二天

scrum 总结&#xff1a; Team member Yesterday’s Work Today’s Work Issue R X Task196:Completed xml 文件的解析&#xff0c;并且通过了两个测试用例 Task198:Completed 添加全局变量&#xff1a;当前会议和remind list Task201&#xff1a;Active 基本完成了select …

千千静听4.6.7版发布了

现在这个版本算是很不错的了&#xff0c;提供了相当完善的播放功能 下载&#xff1a; http://ttplayer.com/ttpsetup.exe 转载于:https://www.cnblogs.com/it201108/archive/2006/04/29/2148385.html

Strategy_Requirement1

以下代码是“策略模式”的第一个例子&#xff1a;

代码解说Android Scroller、VelocityTracker

在编写自己定义滑动控件时经常会用到Android触摸机制和Scroller及VelocityTracker。Android Touch系统简单介绍&#xff08;二&#xff09;:实例具体解释onInterceptTouchEvent与onTouchEvent的调用过程对Android触摸机制须要用到的函数进行了具体的解释。本文主要介绍两个重要…