Go语言非常酷,但并没有为我提供足够的类型安全。如果不需要并发,那么我宁可继续使用Python及其生态环境,而不会去冒险采用Go重写一切。如果需要并发,那我也不会使用Go,因为它缺乏类型安全,这个炸弹肯定会爆炸。
创新互联是一家以成都网站建设、网页设计、品牌设计、软件运维、成都网站营销、小程序App开发等移动开发为一体互联网公司。已累计为成都围栏护栏等众行业中小客户提供优质的互联网建站和软件开发服务。
Rust非常适合并发和安全,尽管futures-rs的“箱子”(Rust里函数库叫做“箱子”)依然非常新。我认为,以后Rust会成为许多后台的默认语言。
Python 是脚本语言,也就是中间件语言,其内核仍然是纯 c 的性能表达的,而主要性能消耗在脚本的实时编译上。而对比c,同样的功能,python可以表达比c更加精炼,当然牺牲了一些性能。如果确实对某个模组性能不满意,还可以使用 c 编写 Python 模块为其加速。面对一些并不需要过多性能而可以获得更快捷的开发速度,Python的优势完全可以盖过“劣势”。可以说,Python基本完美。例如知乎就是使用 Python 制作的。Google 的许多页面也是使用 Python 进行渲染的。
已经有好多程序员都把Go语言描述为是一种所见即所得(WYSIWYG)的编程语言。这是说,代码要做的事和它在字面上表达的意思是完全一致的。 在这些新语言中,包含D,Go,Rust和Vala语言,Go曾一度出现在TIOBE的排行榜上面。与其他新语言相比,Go的魅力明显要大很多。Go的成熟特征会得到许多开发者的欣赏,而不仅仅是因为其夸大其词的曝光度。下面我们来一起探讨一下谷歌开发的Go语言以及谈谈Go为什么会吸引众多开发者: 快速简单的编译 Go编译速度很快,如此快速的编译使它很容易作为脚本语言使用。关于编译速度快主要有以下几个原因:首先,Go不使用头文件;其次如果一个模块是依赖A的,这反过来又取决于B,在A里面的需求改变只需重新编译原始模块和与A相依赖的地方;最后,对象模块里面包含了足够的依赖关系信息,所以编译器不需要重新创建文件。你只需要简单地编译主模块,项目中需要的其他部分就会自动编译,很酷,是不是? 通过返回数值列表来处理错误信息 目前,在本地语言里面处理错误的方式主要有两种:直接返回代码或者抛异常。这两种都不是最理想的处理方式。其中返回代码是非常令人沮丧的,因为返回的错误代码经常与从函数中返回的数据相冲突。Go允许函数返回多个值来解决这个问题。这个从函数里面返回的值,可以用来检查定义的类型是否正确并且可以随时随地对函数的返回值进行检查。如果你对错误值不关心,你可以不必检查。在这两种情况下,常规的返回值都是可用的。 简化的成分(优先于继承) 通过使用接口,类型是有资格成为对象中一员的,就像Java指定行为一样。例如在标准库里面的IO包,定义一个Writer来指定一个方法,一个Writer函数,其中输入参数是字节数组并且返回整数类型值或者错误类型。任何类型实现一个带有相同签名的Writer方法是对IO的完全实现,Writer接口。这种是解耦代码而不是优雅。它还简化了模拟对象来进行单元测试。例如你想在数据库对象中测试一个方法,在标准语言中,你通常需要创建一个数据库对象,并且需要进行大量的初始化和协议来模拟对象。在Go里面,如果该方法需要实现一个接口,你可以创建任何对该接口有用的对象,所以,你创建了MockDatabase,这是很小的对象,只实现了几个需要运行和模拟的接口——没有构造函数,没有附件功能,只是一些方法。 简化的并发性 相对于其他语言,并发性在Go里面显得更加容易。把‘go’关键字放在任意函数前面然后那个函数就会在其go-routine自动运行(一个很轻的线程)。go-routines是通过通道进行交流并且基本上封锁了所有的队列消息。普通工具对相互排斥是有用,但是Go通过使用通道来踢掉并发性任务和坐标更加容易。 优秀的错误消息 所有与Go相似的语言,自身作出的诊断都是无法与Go相媲美的。例如,一个死锁程序,在Go运行时会通知你目前哪个线程导致了这种死锁。编译的错误信息是非常详细全面和有用的。 其他 这里还有许多其他吸引人的地方,下面就一概而过的介绍一下,比如高阶函数、垃圾回收、哈希映射和可扩展的数组内置语言(部分语言语法,而不是作为一个库)等等。 当然,Go并不是完美无瑕。在工具方面还有些不成熟的地方和用户社区较小等,但是随着谷歌语言的不断发展,肯定会有整治措施出来。尽管许多语言,尤其是D、Rust和Vala旨在简化C++并且对其进行简化,但它们给人的感觉仍是“C++看上去要更好”。
【Go语言的优势】
可直接编译成机器码,不依赖其他库,glibc的版本有一定要求,部署就是扔一个文件上去就完成了。
静态类型语言,但是有动态语言的感觉,静态类型的语言就是可以在编译的时候检查出来隐藏的大多数问题,动态语言的感觉就是有很多的包可以使用,写起来的效率很高。
语言层面支持并发,这个就是Go最大的特色,天生的支持并发,我曾经说过一句话,天生的基因和整容是有区别的,大家一样美丽,但是你喜欢整容的还是天生基因的美丽呢?Go就是基因里面支持的并发,可以充分的利用多核,很容易的使用并发。
内置runtime,支持垃圾回收,这属于动态语言的特性之一吧,虽然目前来说GC不算完美,但是足以应付我们所能遇到的大多数情况,特别是Go1.1之后的GC。
简单易学,Go语言的作者都有C的基因,那么Go自然而然就有了C的基因,那么Go关键字是25个,但是表达能力很强大,几乎支持大多数你在其他语言见过的特性:继承、重载、对象等。
丰富的标准库,Go目前已经内置了大量的库,特别是网络库非常强大,我最爱的也是这部分。
内置强大的工具,Go语言里面内置了很多工具链,最好的应该是gofmt工具,自动化格式化代码,能够让团队review变得如此的简单,代码格式一模一样,想不一样都很困难。
跨平台编译,如果你写的Go代码不包含cgo,那么就可以做到window系统编译linux的应用,如何做到的呢?Go引用了plan9的代码,这就是不依赖系统的信息。
内嵌C支持,前面说了作者是C的作者,所以Go里面也可以直接包含c代码,利用现有的丰富的C库。
1.根据Rust的特点和定位适用于对控制性比较强,对性能很敏感的领域,比如底层软件(OS/driver),基础系统软件(Compiler/VM/DB等),性能要求比较高的应用软件(浏览器/图形图像处理/游戏/高性能服务器软件等,或者可能包括近来很火的ML应用方向)。2.底层软件(比如OS/driver)部分是和C应用领域有很大重合度的,在这个领域我认为对C冲击不大。在这里C已经足够好了,而且这些领域技术性很高,但业务逻辑其实并不算太复杂,Rust的优势作用有限。而且Rust相比于C语言,带来了一定的“黑盒”和这些领域一些不需要的语言复杂特性。C作为“可移植的汇编”恰到好处的非常适合这个领域,其他语言基本无法构成挑战。3.前面1中提到的领域除了底层软件(OS/driver之类)剩下的领域,C++目前最具有优势。在这些领域C++相对于C提供了高级特性方便开发,相对于JVM系的性能更高内存更少。(虽然这些领域有些知名软件是C和JVM系的,比如postgresql/redis/nginx/Hadoop/spark等,但在这些领域目前只有C++一个是全能型)我认为rust的主要战场就在这里,需要对决的对手就是C++。C++既有的力量(系统/代码/人员/习惯)太强大了,在这些领域完全打败C++是非常困难的。而且C++也在不断发展,近年来发展的步伐也快了起来,C++11/14/17等等。但C++的历史包袱是很重的,越发展其实复杂性也在不断提高,何况有些问题(像安全/异常/复杂继承等等)是基因里的,通过增加feature打补丁是弥补不了的。Rust最容易吸引的人群可能是C++程序员:因为,一方面解决了不少C++的痛点,另一方面Rust的很多特性其实有点复杂也有点门槛的。这些特性背后的动因有C++背景的程序员是非常容易理解,也是不少C++程序员梦寐以求的。相对而言,其他语言背景出身的程序员,对Rust的共鸣性远远没有C++程序员强烈。猜测Rust会:a.蚕食掉一定的C++份额。一些可能本会选择C++开发的新项目,可能会选择Rust。b.蚕食掉一定的Java份额。有些项目选择JVM系是由于C++开发太复杂,同时该项目对性能又有一定的要求。那么Rust出现以后也会蚕食掉一定的此类项目。c.蚕食掉一定的golang份额。不满意gc(即使1.5改善了,gc的先天问题是无法彻底解决的),不满意泛型,不满意性能的一部分项目。不过也要依赖于Rust未来并发的解决方案是否足够理想了。1.0这种是没戏的。d.移动端Rust从自己实力上说是够的。不过这个真的要看出品移动端设备的“爹”的意思了。Rust自身有一些优势非常明显,在这些领域是很有竞争力的。Rust社区一定要重视IDE开发环境,花费精力出eclipse/intellji/vs的高质量的IDE插件,对于推广和流行大有帮助。只要Rust社区不要犯D语言曾经反复折腾的毛病,能像golang社区那样基础做的不错并且工程质量优秀,那么未来Rust出几个杀手级的应用,前途还是很可期的。
要说性能,那是Rust更好。更多的编译期优化、无 GC 等特点加持,开发高性能应用自然是 Rust 性能高。据统计利用 Rust 开发的 RipGrep 性能甚至赛过使用 C 开发的 Grep。
但是性能不是唯一考量,当你纠结 Borrow Check,纠结 unsafe,纠结 copy clone,纠结各种奇怪的类型限制的时候;当你 cargo build 怒草电脑风扇三分钟的时候;人家 GoLang 可能早就发两个版了。
同时 Rust 的语法花活众多,遍历数组可以写循环也可以 for_each() 一行流。不像 GoLang 那么白开水谁写都差不多一个味道,经常第一天想到神来之笔快乐 Coding 到半夜第二天爬起来发现昨晚写的都甚么东西看不懂不如蜘蛛爬,这是坠痛苦的!
Go 的编译器为了个编译速度快连循环不变式提升、循环展开、对齐等等优化一个都不做,函数内敛一堆限制大多数情况都不做(比如函数里有个 for 或者 defer 或者 select 等,或者函数多于 40 个表达式),拥有的优化一只手都能数的过来:
基础优化欠缺,高级优化更是一个没有,和在 Debug 配置编译下的 -O0 优化的 C++ 差不多一个概念(而且跑得更慢),哪来的资本和 rust 比性能。
其他方面:
而且 Go 的 GC 吞吐量也很低,大多数情况下各方面 Go 跑的甚至都比 Java 更慢。只不过得益于 AOT 编译的设计,相比 Java 而言除了内存占用小和启动速度快之外就没有任何优势了,比较适合拿来做性能不关键的命令行工具。
个人还是更喜欢 Rust。
无论是这几种编程语言被定位于逐步替换 C、C++ ,或者同时存在于程序库中,还是它们会成为未来项目的首选,今天的人们还是会首先选择 C 或 C++——这一切都取决于这些编程语言的能力,尽量发挥它们的长处并且在各自的挑战中获得突破。