`

使用go语言一个月的认识

    博客分类:
  • go
 
阅读更多

年底开始用go重写原来用d的一个小项目,经一个多月使用对go有了初步认识。贴一些go语言特性对比给想入门的朋友做参考,其中涉及自己常用的c++、erlang和d。因为对这些语言掌握程度都只能算入门水平,说错的地方还请大家指正。 

    +   优势 
    -   不足 
    +/- 争议 

    +   属于编译型强类型语言,这点不必多说了 
    +   支持new+垃圾收集,不提供直接手动内存管理(但可以通过malloc外部库实现)。d支持手动管理(delete)及gc操作,可管理c分配内存区。erlang私有堆垃圾收集更高效。 
    +   内建轻量级进程(groutine)和消息传递(chan),可实现Actor模型。erlang直接支持,其他语言可以通过库实现,例如c++ CSP2以及d的Fiber和CSP 
    +/- chan消息类型固定(除非使用empty interface传递任意类型),未提供erlang和scala类型的atom匹配,可通过switch模拟 
    +/- 不支持处理指定类型消息(erlang模式),必须按消息入队列顺序处理 
    +   chan通道支持buffered/unbuffered工作模式,c++ CSP2同样支持 
    +   groutine使用可自增小栈,大量groutine消耗内存更少。d的fiber以及c的ucontext模式同样使用固定栈,erlang表现更好 
    +   提供死锁检测,c++ CSP2支持DeadLock异常 
    +   通过defer语句实现资源释放,c++对象析构以及d的scope提供相似功能 
    +   不提供自动cast,类型转换需要显示操作:float(a_integer) 
    +   支持闭包(closure),可以用来实现函数指针、匿名函数和函数嵌套。这年头似乎流行的语言多少都有支持::erlang提供fun这一基本类型,d语言有类似C#的delegate(d1.0没有保存上下文,2.0开始支持上下文完整闭包),至于c++各种技巧性实现就暂且不提了 
    +   动态类型,可以借助interface提取配合内建反射机制进行匹配,参见fmt库Printf实现 
    +   多返回值,d/c++甚至c都可以直接或仿真实现 
    +   struct支持嵌入(数据继承)与匿名成员,调用指定receiver的函数时自动匹配(例如Mutex.Lock),但不支持c/c++的bit field,这一点和d相同 
    +   数组可动态增长,d语言内建支持,c++可以使用库实现 
    +   支持slice:提高数据引用效率,减少缓冲溢出风险,不足是不能作为l-value,与d的slice相比稍逊一筹 
    +   内建utf8编码string,构建后内容不可变,实现了基本字符串操作函数 
    +   支持包一级初始化,Plan 9的c编译器已经开始支持,d同样提供模块初始化功能 
    +   全部变量自动初始化成0,避免c/c++中出现的垃圾数据。d语言具有相同设计,想必主要是为了照顾gc,不然一大堆垃圾数据难以从中识别出有效指针 
    +   支持单元测试和文档生成:java、d、c++等语言同样内建或通过外部支持 
    +   语法改进(包括一些语法糖) 
        减少括号分号:for、if、switch等不需要括号,同时行尾不强制分号,分号仍可作为语句分隔用 
        for:替代while,不支持逗号语法,暂未发现do while替代方式。配合range提供foreach语法,可对数组、片断(slice)、map或其他实现interable接口的类型进行迭代操作,同时for ... range还可以循环接收chan消息管道数据直到管道关闭 
        if: if a = b; a {},和c语言中if (a = b, a)作用相同 
        break、continue:支持lable(d、java都有) 
        switch:case语句支持逗号分割多个数值以及非常量表达式评估(gcc扩展支持范围匹配),当前case分支执行后自动break,使用fallthrough进入后续case 
        select:同时等待多路事件源(chan通道) 
        struct:分配、初始化语法灵活方便,取栈变量地址自动复制;支持struct嵌入(类似d等语言的mixin)以及匿名成员自动引用(记得Plan 9的c编译器好像也支持) 
        var/=/:= 支持同时定义多个变量以及a,b = b,a交换语法,支持类型自动推测,和d/c++ 0x的auto效果相似 
        import:同时导入多个包,别名导入,名字空间访问方便 
        const:可以代替enum,使用iota根据开始定义的规则实现自增 
        goto:继续支持 
        ->:指针引用不用写->比c和c++方便些,这方便d早已统一 
    +/- 将赋值操作定义成语句而非c的表达式,j就是说b=(a=1)这种写法无效 
    +/- 支持指针但不支持指针运算(包括++/--),据说出于安全考虑 
    +/- 数值变量只支持a++而省略++a形式,且视为表达式(b=a++不再合法) 
    +/- 独特的访问控制模型:首字母大写表示public属性,小写字母struct或成员只能在包内访问,这点有些fortran的感觉 
    +/- 将未使用引入(import)与变量视为编译错误,无用变量可以用类似erlang的下划线(_)乎略 
    +/- 内建map(同d语言),但不允许struct作为key,同样可以通过库实现 
    +/- 与众不同的对象实现方式:不直接提供类与继承,通过struct实现类。方法是定义包含receiver的func给struct绑定成员函数(须和struct放在相同包中),基本类型定义别名后也能绑定。 
    +/- 灵活但独特的interface,若struct实现了interface声明的方法则视为实现此interface。可以通过 InstanceInterface.(InterfaceType)动态提取接口,类似COM中IUnknown::QueryInterface;或用InstanceInterface.(Type)作unbox操作,将interface转换成Type类型 
    +/- 简约设计,没有范型、模板、函数和操作符重载、异常处理等,据文档说一些是出于设计考虑,另外部分功能酝酿中 
    +/- 未提供传统并发访问机制(例如barrier等),提供Mutex、Once、chan等同步手段,官方建议应通过消息而非共享内存进行共享。但消息传递同样涉及到数据驻留模型,go只将string设计成immutable,其它类型传递仍需要使用指针或创建拷贝,效率可能受到影响。erlang全部类型immutable(除ets),大块二进制数据自动通过引用计数在共享堆中共享,d并发模型设计则已经包含immutable/shared关键字(尚未完成) 
    -   目前不支持Windows系统,mingw移植版本还只能编译简单程序 
    -   select所等待的事件源必须是编译时预知的,不支持FD_SET的集合模式,且case处理优先级无法自定义(文档说明为随机,可能内建公平调度逻辑),这两点不如c++ CSP2灵活。 
    -   8g+8l/6g+6l: 
        目前生成代码效率稍低。已经列入语言发展计划,正在改进中。 
        全部import库静态链接至目标程序生成代码尺寸大 
    -   不支持asm嵌入,Plan 9的c编译器同样不支持。常见的c和d编译器都可以嵌入汇编,对于系统语言来说似乎有必要,不过Plan 9认为能够外联汇编目标文件已经足够了。 
    -   闭包是c模式的,不能隐含携带对象(struct)指针,使用略为不便 
    --  可用库少,主要是缺少高级网络、gui、数据库访和媒体处理库。为解决goroutine调用外围代码产生的阻塞,包括libc在内的底层支持包全部需要重新实现(对内部轻量级调度进行封装),成为直接使用现有c/c++库的最大障碍 
    --  使用ffi调用现有c代码不方便,需要编写接口go文件再通过cgo生成多个中间文件通过gcc编译链接产生最终动态库(使用$GOROOT/misc /cgo目录下Makefile模板),但目前ffi调用外部.so库路径固定指向$GOROOT/pkg/$GOARCH,难以脱离开发环境发布。 
        当前ffi方式只能单向调用c库(go需保持指针防止被垃圾收集,和JNI原理类似),c代码不允许直接回调go(可管道通讯模拟回调但使用不便)。这方面d语言稍具优势,d 2.0提供一定c++兼容性;erlang具备多种跨语言调用模型,R13 B03加入NIF使用更方便。 
    --  不具备动态模块加载能力,暂时不适用于依赖动态插件技术的项目 
    --  调度器尚不完善。为利用多核、多CPU并发计算能力需要手动设置环境变量GOMAXPROCS大于1,但会导致goroutine通过线程切换调度,ping-pong类测试效率急剧下降。此外进行1000万次token传递,1个goroutine耗时5秒,100个10秒,1000个goroutine传递就要20秒,说明除掉cache命中率下降因素外调度算法的效率也有优化余地(实现类Linux的O(1)调度),这方面和erlang差距还比较大(进程数量增加对效率影响较小)。 
    --  gccgo:基于gcc后端的另一个go编译器,编译不成功未实测,以下结论根据文档得出 
        代码效率更高(得益于gcc backend)但编译速度稍慢 
        可以直接和gcc代码链接 
        尚未实现垃圾收集,不能运行实际项目 
        goroutine通过pthread实现,调度开销大且栈空间占用多,无法大量使用 

分享到:
评论
1 楼 jacking124 2013-02-24  

相关推荐

    Go语言学习之认识Golang

    Go语言学习之认识Golang,认识golang很久了,中断一段时间后,发现遗忘了。现在重新整装待发,重新学习下基础知识。

    Go语言实战 中文高清带目录

    Go语言实战 中文高清带目录。 本书是国外 Go 社区多年经验积累的成果。本书默认读者已经具有一定的编程基础,希望更 好地使用 Go 语言。全书以示例为基础,详细介绍了 Go 语言中的一些比较深入的话题。对于有经 验的...

    Go语言入门基础教程–Let’s go

    今天我们将认识Go语言是什么?探讨Go能用来做什么?还将使用Go语言的基础语法进行实践操作. 什么是Go语言 Go 是一个开源的编程语言,它能让构造简单、可靠且高效的软件变得容易。 Go 是一种静态强类型、编译型、并发型...

    想系统学习GO语言(Golang),能推荐几本靠谱的书吗?

    学习任何一门语言,都要...现在对Go语言应该有了一个全面的认识,然后你再结合Go语言圣经这本书,深入理解Go的基础。 Go语言圣经中文版 https://www.gitbook.com/book/yar999/gopl-zh/details 然后通过《Go语言实战》

    Go语言的内存模型及堆的分配管理

    这是Go语言成为高生产力语言的原因之一。 我们不需要精通内存的管理,因为它确实很复杂,但掌握内存的管理,可以让你写出更高质量的代码,另外,还能助你定位Bug。这篇文章采用层层递进的方式,依次会介绍关于存储...

    7章Go从入门到进阶,大厂案例全流程实践

    Go语言,也被称为Golang,是由Google公司开发的一种静态强类型、编译型并具有垃圾回收功能的编程语言。Go语言在2009年首次发布,设计目标是简洁、高效、安全和并发,旨在提供一种易于编写和维护的系统级编程语言...

    Go语言 channel如何实现归并排序中的merge函数详解

    初识go语言不到半年,我是一次偶然的机会认识了golang这门语言,看到他简洁的语法风格和强大的语言特性,瞬间有了学习他的兴趣 最近学习 Go,但是苦于没有项目练手,于是便逼迫自己:如果想到什么有趣的东西,看能不能...

    Go 学习笔记

    很全的go语言学习比较,对比python能对go语言能有一个较为全面的认识

    自己动手写docker 陈显鹭

    阿里的工程师将自己的经验共享出来,写了这本书,详细讲解容器的原理,并且使用go语言写了一个docker,为大家提供一个学习容器原理的方法。 <br/>本书在详细分析Docker所依赖的技术栈的基础上,一步一步地通过...

    对Golang的nil的理解和认识

    按照Go语言的规范,任何类型在未初始化的时候都对应一个零值: 布尔型零值为:false 整型零值为:0 字符串的零值为: 而指针,函数,interface,slice,channel,map的零值均为nil Go文档中说明:nil是预定义的...

    GO语言实现的端口扫描器分享

    //GO语言 实现端口扫描  //缺陷  //port 无法设置成全局变量不知道怎么设置的  //var l = list.New() 这个是数组操作并不是消息队列 跟消息队列功能类似  //实现功能  //实现生成 IP段  //实现端口扫描  ...

    golang学习笔记

    这是golang语言学习笔记,记录go艳艳学习中的比较重要的点,适合初学者在学习go之前大致浏览,对golang有初步认识

    Go Web 编程 开源文档

    Go 是 Google 开发的一种编译型,并发型,并具有垃圾回收功能的编程语言,是一种你值得认识一下的语言:  如果你想学习 Go,请关注这本开源书。  开源书籍《Go Web 编程》现在在 Github 上,...

    Golang中的网络乐趣-Golang开发

    支持的版本v1.4 v1.5 v1.6 v1.7 v1.8 v1.9 Intro Nah,而不是另一个Web Framework,我们已经足够了。我们在Go上花费的时间越多,就越清楚地认识到最轻巧,最纯净的内容。 -stdlib约定确实可以扩展到大型开发人员群体...

    leetcode添加元素使和等于-go-ccmouse:去鼠标

    leetcode添加元素使和等于 ...让大家对Go语言有一个初步的认识! 共 7 节 (85分钟) 收起列表 2-1 变量定义 (11:04) 2-2 内建变量类型 (17:21) 2-3 常量与枚举 (07:00) 2-4 条件语句 (09:39) 2-5 循环 (09

    leetcode添加元素使和等于-learngo:学习

    让大家对Go语言有一个初步的认识! 2-1 变量定义 2-2 内建变量类型 2-3 常量与枚举 2-4 条件语句 2-5 循环 2-6 函数 2-7 指针 第3章 内建容器 本章节我们来学习数组,切片,Map和字符串。在Go语言中,我们一般不直接...

    Rust专栏前言:Rust优势和前景展望

    事实上,目前最有名的基于Rust语言的项目就是脸书的Libra,这是一个区块链界的颠覆性项目,该项目自问世到现在,一直争议不断。巧合的是,就在前两天,脸书CEO在美国国会听证会为Libra辩护:若遭阻止,中国将...

    Yaml文件的基础知识.docx

    yaml文件 软件开发过程中,配置文件是...json文件:现在前后端交互的行业标准,搞互联网的没有人不认识,但有个头痛的地方就是不能注释(可以写一个不用的字段把注释内容写进去,但不建议)。 yaml文件:比较新的一种

    mydocker:<<自己动手写docker >>

    本书在详细分析Docker所依赖的技术栈的基础上,一步一步地通过代码实例,让读者可以自己循序渐进地用Go语言编写出一个容器的引擎。书籍,书籍意图在提供给读者一条动手路线,一步一步地实现Docker的隔离性,构建...

    入门学习Linux常用必会60个命令实例详解doc/txt

    -F:这个命令通常和-a一起使用,它会为每一个mount的动作产生一个行程负责执行。在系统需要挂上大量NFS文件系统时可以加快加载的速度。 -f:通常用于除错。它会使mount不执行实际挂上的动作,而是模拟整个挂上的...

Global site tag (gtag.js) - Google Analytics