从C++到GO
从C++到GO
刚开始接触Go语言,看了两本Go语言的书,从c++开发者的角度来看看go语言的新特性,说下自己感触较深的几点:
并发编程
Go语言层面支持协程,将并发业务逻辑从异步转为同步,大幅提高开发效率;
在c++中,做并发编程目前主流的方案是事件驱动(单线程/多线程/多进程模型等),而事件驱动就需要一个IO多路复用的分发器(select/epoll),这样,就造成了业务逻辑的断开,在代码层面为异步模型,比如:
1).先是一段业务代码
2).调用IO(业务断裂)
3).IO完成后的后续处理逻辑;
而go中的协程的支持让这样的开发工作就轻松多了,按照同步的方式顺序写业务逻辑,遇到IO也没关系,一个线程中可以创建成上百万个协程,这个协程阻塞了就跑下一个,不需要应用代码层面来负责IO后续调度的处理;
比起自己用C/C++去封装底层或调用libevent之类的库,Go的优势是将事件机制封装成了CSP模式,编程变得方便了,但是需要付出goroutine调度的开销;
ps1:Go语言标准库提供的所有系统调用操作(当然也包括所有同步IO 操作),都会出让CPU 给其他goroutine;
ps2:看过网上的经验数据,同步和异步的开发效率(不是运行效率,指的是出活速度)差不多是4:1,嘿嘿,这个数据好激动~~
关于事件驱动与协程在处理并发上的对比,详见不鳥萬Rio的回答:
https://www.zhihu.com/question/19585576/answer/12424447
垃圾回收
毫无疑问这个好用,有了垃圾回收,不需要开发者自行控制内存的释放,这样可避免一堆问题(重复释放、忘记释放内存、访问已释放的内存等);
当然,c++11引入的智能指针(unique_ptr等)如果在程序中应用的普遍,也可以达到类似垃圾回收的目的;
GC带来的问题也是有的,会造成STW,会有程序停止调度的卡顿;
Go1.5的GC利用各种手段大大缩减了STW的时间。Go语言官方保证,在50毫秒的Go程序运行时间中因GC导致的调度停顿至多只有10毫秒。
(ref:http://www.infoq.com/cn/articles/2015-review-go)
函数多返回值
这在python里算不得什么新鲜事,但对c++来说,要实现函数返回多个数据,要么封装一个结构体,要不就只能通过函数传参实现;
多返回值这玩意,在码字的时候能提升心情愉悦感啊,想想,在要返回多个值的场景,不用再找个地方用一个结构体封装一下,直接返回,多直接:
func getName()(firstName, middleName, lastName, nickName string){
return "May", "M", "Chen", "Babe"
}
错误处理
提到多返回值,就接着说说错误处理,估计多返回值应用最多的场景就是第二个参数传回函数的错误状态;比如以下写法就很常见了:
if result, ok := moreMagic(); ok {
/ Do something with result /
}
c/c++对错误的处理一般都是通过错误码来确定一个函数是否正确调用,因此相比c/c++而言,go的错误处理代码行减少了,看上去也美观优雅;
go引入了3个关键字(defer、panic和
recover)用于标准的错误处理流程;defer关键字的引入,保证错误处理的代码在发现错误时一定能够被调用,不会因为业务分支逻辑上的修改而漏调;
当然,看和谁比了,python的实践者认为没有使用try catch的异常处理机制,让错误处理显得很繁琐;
Russ Cox指出Go语言是为大型软件设计的,Go语言的返回错误方式,不可否认,对于调用者不是很方便,但这样做会让程序中可能会出错的地方显的很明显。对于小程序来说,你可能只想打印出错误,退出程序。对于一些很精密的程序,根据异常的不同,来源的不同,程序会做出不同的反应,这很常见,这种情况中,try + catch的方式相对于错误返回模式显得冗长。
ref:
Go语言的错误处理机制引发争议
http://www.infoq.com/cn/news/2012/11/go-error-handle
函数的地位提升
函数作为“类型”出现,成为了一等公民;可以定义函数类型,将一个函数赋值给函数变量,然后在业务链中传递,这个在c++中只有使用std::function才能做到;
还可以使用匿名函数(对应c++11中的lambda表达式),在语言层面支持函数编程,从而可以对程序进行更加灵活的控制和管理。
强制的编码规范
系统做大做久了,代码质量难免下降;开发人员的代码风格不一致,导致程序中充斥着千奇百怪的命名及类的组织方式;
是的,是个公司就会有代码规范,但那只是写在纸面上的东西,是否真照着执行了,还真不好说;什么后期扫描,不改不给上线?
为工程而生,go强制的编码规范,让人耳目一新,从命名、到代码排列组织方式都有明确的规定,不符合就不能编译通过!这个真得叫好;代码工程不是实现个性张扬的地方;
语法后置,为啥这么搞?
以上聊到的都是go的优点,看一个爽一个;但go的语法,如变量、函数的声明和定义,和我们常见的语言语法相比,都是类型后置,这点着实有些不习惯;
为啥要这么搞?
Rob Pike(go语言的创建者之一)针对这个问题给过解释:不是为了与众不同,而是为了更加清晰易懂。特别是当类型比较复杂时,Go的类型语法要比 C 的容易懂。
详见:
https://www.zhihu.com/question/21656696/answer/19027040
最后,贴几点Go语言的哲学:
Go语言集众多编程范式之所长,并以自己独到的方式将它们融合在一起。程序员们可以用他们喜欢的风格去设计程序。
相对于设计规则上的灵活,Go语言有着明确且近乎严格的编码规范。我们可以通过“go fmt”命令来按照官方的规范格式化代码。
Go语言是强调软件工程的编程语言。它自带了非常丰富的标准命令,涵盖了软件生命周期(开发、测试、部署、维护等等)的各个环节。
Go语言是云计算时代的编程语言。它关注高并发程序,并旨在开发效率和运行效率上取得平衡。
Go语言提倡交换数据,而不是共享数据。它的并发原语Goroutine和Channel是其中的两大并发编程利器。同时,Go语言也提供了丰富的同步工具,以供程序员们根据场景选用。然而,后者就不属于语言级别的支持了。
http://www.infoq.com/cn/articles/go-language-introduction
Posted by: 大CC | 26JAN,2016
博客:blog.me115.com [订阅]
Github:大CC
随机推荐
- AFNETWorking 不支持中文URL请求
p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px Menlo; color: #000000; min-height: 16.0px } p.p ...
- iOS 版 MWeb 发布到自建 Wordpress 和 Metaweblog API 使用指南
MWeb 的发布服务的使用方法是先增加发布服务,再使用.在 iOS 中,要增加发布服务,可以在首页中,点左上角的 "设置" 按钮,进入设置界面,并滑动到底部,就会看到增加发布服务的 ...
- 罗永浩专访全文记录(转自好奇心日报-http://www.qdaily.com/)
这篇文章是转的,存档做记录,定期看一看,激励自己遇到到困难时,想想人家比自己难多了,自己那点事算个屁啊.学习别人,不要带有傻逼主观倾向性,这样什么也得不到,我看完后,发现有一句话,说的非常好,自己有自 ...
- django的分页
一.分页器的函数封装 # 分页计算最小页和最大页 def page_list_return(total, current=1): ''' 分页,返回本次分页的最小页数和最大页数列表 :param to ...
- "_OBJC_CLASS_$_AddFriendPageItem", referenced from:
该出错是指:有些头文件没有导入到 TARGETS 中的Build Phases - Compile Sources 中
- 详解JS跨域问题
什么是跨域? 概念:只要协议.域名.端口有任何一个不同,都被当作是不同的域. JavaScript 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ...
- j2ee部分
j2ee部分 1.BS与CS的联系与区别. C/S是Client/Server的缩写.服务器通常采用高性能的PC.工作站或小型机,并采用大型数据库系统,如Oracle.Sybase.InFORMix或 ...
- java类
1.四种访问控制符 private.不指明.protected.public 2.构造函数没有返回值 是因为构造函数默认返回的是类的实例对象.所以不需要写返回值 3.static static表示类拥 ...
- Apache 打开网页的时候等待时间过长的解决方案
服务器搭建后经常在打开页面的时候,等待很长时间,有时候,都超过一分钟了,然后才能打开,但是打开后,速度又很快,休息一会再点击,又会很慢了,遇到了这种问题很头疼,由于不是专业做服务器配置的,所以刚开始没 ...
- Python中的传值和引用
我写这个主要是给自己看,内容也就是便于自己理解,可能会不正确,但目前来看代码测试的结果是对的. python中一切皆对象. 当我们赋值时: a = 1 其实是先创建了一个整数常量1(也是一个对象,且已 ...