从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
随机推荐
- 我的AngularJS 学习之旅
我的AngularJS 学习之旅 基础篇 1.Angular的 起源 2.比较Web 页面实现的几种方式 3.一些基本术语 4.Angular与其他框架的兼容性 5.总结 6.综合实例 很早之前就 ...
- ajaxfileupload 传参数
引用:http://www.cnblogs.com/lyeo/archive/2012/05/11/2496261.html 直接上代码: var data = { name: 'my name', ...
- MapReduce 简介
2. MapReduce 简介 MapReduce 实际上是分为两个过程 map 过程 : 数据的读取 reduce 过程 : 数据的计算 并行计算是一个非常复杂的过程, mapreduce是一个并行 ...
- 镁光c400-MTFDDAK064M固态硬盘更新固件
前段时间笔记本不停地假死机,就是那种系统停止响应,但鼠标依然有动作的死机,各种烦人,后来检测了下系统的温度,发现cpu轻易地上了75度,甚至会到94度,以为风扇该清理了,硅胶该换了,回想了一下,离上次 ...
- switch 与 python字典
python 中并没有switch语句,但是有一个数据类型与switch语句特别相似,它就是 dict{ key: value, ...} 下面用 dict{ key:value,..} 来简单的实现 ...
- 最常用的截取函数有left,right,substring
最常用的截取函数有left,right,substring 1.LEFT ( character_expression , integer_expression ) 返回从字符串左边开始指定个数的字符 ...
- linux内核的makefile.txt讲解
linux内核的linux-3.6.5\Documentation\kbuild\makefiles.txt Linux Kernel Makefiles This document describe ...
- If you only do what you can do you'll never be more than you are now.
If you only do what you can do you'll never be more than you are now. 如果你只是做你力所能及的事,你将不会有所进步:
- MySQL免安装数据库配置-Windows8.1
1. 解压Mysql压缩包,将包中my-default.ini复制一份,改名为my.ini,添加一下配置信息到my.ini: [client] port=3306 default-character- ...
- android中webrtc的几个关键的状态
在android层使用webrtc的时候,都是通过native层回调的形式来触发ui的改变,比如在什么时候绘出对方的视频窗口,什么时候表示双方连接已经建立等等... 我现在把我知道的列出来用于备忘. ...