作者 openkk 2012-03-04 18:26:58

文/Windstorm

有一段时间没更新了。最近在忙一个 Server+Client 的项目,Client 是 Android 手机,大概也就是几十的规模。Server 是纯 Golang 实现,没有 apache 或者 ngix 这种 web server,也没有数据库,自己写了个文件管理 module,handle 这种小规模的服务没问题。算下来接触 Golang 也有四个多月了,断断续续写了一些东西,这里纪录一下心得吧

先大概说下为什么用 Golang。我是一个对语言有洁癖的人,曾经是一个C+Python 的坚定呐喊者,最常说的一句话就是,只要熟练这两种,什么情况都能应付,根本不用 Java 和 C++(纯指我所在的领域)。核心代码用C,速度快,需要记的语言细节少;外围用 Python glue,灵活,简洁,任何模块都容易上手,绝配。Java 的繁琐,C++ 的无数无用的特性,都让我只在不得不用的时候才去用。Objective-C 是另一个我欣赏的语言,问题是不跨平台,过于封闭。

可惜的是,在这个节奏极快的时代,不是所有情况下都适合上C。之前有一个项目也是类似的架构和规模,为了节省时间,当初几乎没有服务器平台编程经验的我,在服务器端选择用 Django+Apache+MySQL  做,成熟,社区活跃,又是 Python 作为主要开发语言,这些都是这个选择的原因。说实话,几个月过去后,回首看,这不是一个愉快的经历。Django 是一个好架构,大而全,而大而全有时也就意味着臃肿,五花八门的配置,过紧的模块耦合对引入第三方工具限制颇多,自带的 ORM 又不好用。之前从来没有搞过服务器配置的我,对 Apache 的配置和效率所带来的琐碎的东西也头疼。总的来说这个部分花了我很多时间,有新手学习服务器编程的必经过程,也有折腾 Django 和 Apache 没必要的时间浪费,很大部分上抵消了 Python 带来的快速开发的灵活性。而一旦服务器上线,动态语言带来的一些 bug 又会让人头疼。对于普通高校实验室这种没有完善的服务器调试的条件,基本就是改了就上线用,有些隐蔽 bug 到某些条件分支才会触发,一旦在运行中途出问题,改起来也麻烦。

从那时起,我就特别想,要是有一种语言能把 C 和 Python 的优点结合起来,也就是说

  • 速度快,高性能
  • 简洁明了,需要记的语言细节少,开发迅速(C)
  • 灵活,开发快速,类 Python 的 list,map 等常用数据结构支持(Python)
  • 完善的模块支持,模块也容易上手(Python)
  • 对程序员友好的并行架构(Erlang)
  • 安全,绝大部分问题能消灭在 compile time 中(C minus pointer)

那基本就是系统级和网络级编程最对我胃口的语言了。然后我就找到了 Go

Golang 是一个新语言,截至目前为止,第一版正式版还没有发布。Golang 的设计者是 Robert Griesemer, Rob Pike 和 Ken Thompson,当年设计 C 和 Unix,后来的 Plan9 团队中的人 。Golang 的设计理念很明确,就是将动态类型语言的编程容易度和静态类型语言的安全效率结合起来。如果你想更深入了解 Golang 的发展历史以及完整的目标,请参考 Golang FAQ

当然,Golang 吸引我的地方,不是因为其是 Google 出品,也不是因为其设计者皆为大牛,而是因为,Golang 真的做到了它所宣称的目标。Golang 就如同 C 和 Python 中间的完美结合,如果你是 Python 爱好者,又追求代码的速度和并行化,那么简单说,Golang 就是为你设计的。Golang 有很浓厚的C的遗风,尽量屏蔽 C++ 和 Java 的影响,比如没有独立的 OO 体系(并不是说不能 OO),一切以 struct 为中心,没有 exceptions (Oh yes!),仍然有指针,等等。但是,Golang 又吸取了很多新语言的精华,并带有自己独特的设计。比如:

1. 保留但大幅度简化指针

Golang 保留着C中值和指针的区别,但是对于指针繁琐用法进行了大量的简化,引入引用的概念。所以在 Golang 中,你几乎不用担心会因为直接操作内寸而引起各式各样的错误。

2. 多参数返回

还记得在C里面为了回馈多个参数,不得不开辟几段指针传到目标函数中让其操作么?在 Go 里面这是完全不必要的。而且多参数的支持让 Go 无需使用繁琐的 exceptions 体系,一个函数可以返回期待的返回值加上 error,调用函数后立刻处理错误信息,清晰明了。

3. Array, slice, map 等内置基本数据结构

如果你习惯了 Python 中简洁的 list 和 dict 操作,在 Golang 中,你不会感到孤单。一切都是那么熟悉,而且更加高效。如果你是 C++ 程序员,你会发现你又找到了 STL 的 vector 和 map 这对朋友。

4. Interface

Golang 最让人赞叹不易的特性,就是 interface 的设计。任何数据结构,只要实现了 interface 所定义的函数,自动就 implement 了这个 interface,没有像 Java 那样冗长的 class 申明,提供了灵活太多的设计度和 OO 抽象度,让你的代码也非常干净。千万不要以为你习惯了 Java 那种一条一条加 implements 的方式,感觉还行,等接口的设计越来越复杂的时候,无数 Bug 正在后面等着你。

同时,正因为如此,Golang 的 interface 可以用来表示任何 generic 的东西,比如一个空的 interface,可以是 string 可以是 int,可以是任何数据类型,因为这些数据类型都不需要实现任何函数,自然就满足空 interface 的定义了。加上 Golang 的 type assertion,可以提供一般动态语言才有的 duck typing 特性, 而仍然能在 compile 中捕捉明显的错误。

5. OO

Golang 本质上不是面向对象语言,它还是过程化的。但是,在 Golang 中, 你可以很轻易的做大部分你在别的 OO 语言中能做的事,用更简单清晰的逻辑。是的,在这里,不需要 class,仍然可以继承,仍然可以多态,但是速度却快得多。因为本质上,OO 在 Golang 中,就是普通的 struct 操作

6. Goroutine

这个几乎算是 Golang 的招牌特性之一了,我也不想多提。如果你完全不了解 Goroutine,那么你只需要知道,这玩意是超级轻量级的类似线程的东西,但通过它,你不需要复杂的线程操作锁操作,不需要 care 调度,就能玩转基本的并行程序。在 Golang 里,触发一个 routine 和 erlang spawn 一样简单。基本上要掌握 Golang,以 Goroutine 和 channel 为核心的内存模型是必须要懂的。不过请放心,真的非常简单。

7. 更多现代的特性

和C比较,Golang 完全就是一门现代化语言,原生支持的 Unicode, garbage collection, Closures (是的,和 functional programming language 类似), function 是 first class object,等等等等。

看到这里,你可能会发现,我用了很多轻易,简单,快速之类的形容词来形容 Golang 的特点。我想说的是,一点都不夸张,连 Golang 的入门学习到提高,都比别的语言门槛低太多太多。在大部分人都有C的背景的时代,对于 Golang,从入门到能够上手做项目,最多不过半个月。Golang 给人的感觉就是太直接了,什么都直接,读源代码直接,写自己的代码也直接。

有朋友要抗议了,你把 Golang 吹的这么好,难道它就没有缺点?有,当然有,不过和它的优点比,我觉得很多缺点都是因为整个语言太新,不成熟,随着时间的推移都能得到解决,相比之下都能忍了。如果你希望进一步了解 Golang 的优缺点,可以参考以下 yufeng 写的这篇文章,系统编程语言明日之星—Go(http://blog.yufeng.info/Go.pdf)。

还有朋友要说,Golang 这么好,为什么没人用?我想说,眼界放开点,这个世界精彩的东西比你想象的多。Golang 被 Google 用于 Youtube 的数据库,被越来越多的国外公司(大部分创业公司)用于后端开发,甚至在天朝,也有完全用 Golang 做服务开发的云应用公司了。可以说,随着 Go 1 即将到来的正式推出,Golang 的使用范围,应该会越来越广。

好,总结时间

如果你是 Python 和动态语言狂热爱好者,Go 不一定能给你带来很大的惊喜,这纯粹取决于你的项目性质,考虑到 Python 目前在很多地方都用C做核心运算,速度在大部分情况下都不是大问题。scalability 是一个问题,但并不是人人都会遇到的。

如果你是C爱好者,强烈建议你学习和使用 Go。Go 可以调用 C/C++ 程序,又提供了太多的便利,速度上稍有牺牲,但并不大。在绝大部分场景下 Go 能给你带来媲美C的性能,而对于某些确实性能过于关键的场合,也可以通过 cgo 让 Go 和C搭配。

如果你是 Java 爱好者,除非你是做 Android 这种不得不用 Java 的平台,否则也建议你尝试学习 Go,这个开发上感觉的差异如同比较开载着 1 吨石头的拖拉机和开保时捷 911 那么明显,而 Java 能给你的,Go 能给得更好。

如果你是 C++ 爱好者,!@#$%^&*,恭喜你,至少你的智商应该是没问题的。人生苦短,赶紧脱离 C++ 这个苦海吧。你用来学 89 个 C++ 高级特性的时间,估计已经用 Go 写了 64 个开源项目了。

如果你是像我一样的 C 和 Python 的爱好者,对动态语言又没有特殊的热爱……我还需要说什么呢?

使用Go语言一段时间的感受的更多相关文章

  1. 这段时间对c#和java的感受

    这段时间对c#和java的感受 虽然很多书上说语法相似,但实际这是一个接近于门外汉的看法 真正的不同是 c#对更贴近系统API,      而java倡导跨平台 因而c#语法关键字更多,更细, 而ja ...

  2. 专访黄勇:Java在未来的很长一段时间仍是主流(把老板当情人,把同事当小孩,把客户当病人)

    url:http://www.csdn.net/article/2015-09-06/2825621 2015-09-06 13:18 摘要:本文采访了现任阿里巴巴公司系统架构师黄勇,从事近十年的Ja ...

  3. worker 启动时向 etcd 注册自己的信息,并设置一个带 TTL 的租约,每隔一段时间更新这个 TTL,如果该 worker 挂掉了,这个 TTL 就会 expire 并删除相应的 key。

    1.通过etcd中的选主机制,我们实现了服务的高可用.同时利用systemd对etcd本身进行了保活,只要etcd服务所在的机器没有宕机,进程就具备了容灾性. https://mp.weixin.qq ...

  4. 接下来一段时间会对大家进行网络通信的魔鬼训练-理解socket

    引子 下一篇标题是<深入理解MQ生产端的底层通信过程>,建议文章读完之前.或者读完之后,再读一遍我之前写的<RabbitMQ设计原理解析>,结合理解一下. 我大学时流行过一个韩 ...

  5. 从配置读取一段时间(TimeSpan)

    C#的TimeSpan表示一段时间,DateTime表示一个时间点.TimeSpan可正可负,可与DateTime相加减,很方便,我喜欢. 代码中我们经常要表示一段时间,用一个统一的单位(时 或者 分 ...

  6. Win8.1开机黑屏一段时间才能登录

    最近发现开机后有一段时间黑屏过后才能进人登录界面,并且时间越来越长,网上查询了很多方法都没有效果,只能自己找了. 网上有一种方法提到用msconfig诊断判断或者安全启动来查看是否有黑屏,于是试了一下 ...

  7. 关于ScheduledExecutorService执行一段时间之后就不执行的问题

    在项目中使用java的定时任务时,有的时候执行一段时间后没任何反应了.这里有篇文章说了这个问题.猛击下面的链接. http://blog.163.com/scuqifuguang@126/blog/s ...

  8. C#实现每隔一段时间执行代码(多线程)

    总结以下三种方法,实现c#每隔一段时间执行代码: 方法一:调用线程执行方法,在方法中实现死循环,每个循环Sleep设定时间: 方法二:使用System.Timers.Timer类: 方法三:使用Sys ...

  9. IIS服务器运行一段时间后卡死,且无法打开网站(IIS管理无响应,必须重启电脑)

    问题描述: 公司希望使用IIS配合网站显示一些订单跟进的情况并展示出来,所以我们在一台演示的Win7 Pro电脑上安装了IIS,但使用了一段时间后发现每过几天页面就无法正常访问了,而且打开IIS管理器 ...

随机推荐

  1. 树莓派Raspberry实践笔记—显示分辨率配置

    转载:http://www.cnblogs.com/atsats/p/6607886.html 如果未接显示设备,使用VNC登录后,显示分辨率很小,应该是480p,导致使用很不方便. 这里通过修改/b ...

  2. Educational Codeforces Round 82 A. Erasing Zeroes

    You are given a string ss. Each character is either 0 or 1. You want all 1's in the string to form a ...

  3. JavaScript动画相关

    JS动画原理 通过CSS缓慢变化从而实现动画效果 获取css属性 Window.getComputedStyle()方法返回一个对象,该对象在应用活动样式表并解析这些值可能包含的任何基本计算后报告元素 ...

  4. Update(Stage4):sparksql:第5节 SparkSQL_出租车利用率分析案例

    目录: 1. 业务2. 流程分析3. 数据读取5. 数据清洗6. 行政区信息 6.1. 需求介绍 6.2. 工具介绍 6.3. 具体实现7. 会话统计 导读 本项目是 SparkSQL 阶段的练习项目 ...

  5. problem :无法显示activemq的管理界面

    点击 Manage ActiveMQ broker 无法显示admin界面 解决方法:修改activemq.xml 和 jetty.xml文件 把所有0.0.0.0修改为127.0.0.1 成功: 账 ...

  6. 栈的python实现

    栈,又名堆栈,它是一种运算受限的线性表.其限制是仅允许在表的一端进行插入和删除运算.这一端被称为栈顶,相对地,把另一端称为栈底. 向一个栈插入新元素又称作进栈.入栈或压栈,它是把新元素放到栈顶元素的上 ...

  7. 操作系统OS,Python - 协程(Coroutine)

    留坑 参考: https://en.wikipedia.org/wiki/Coroutine https://zh.wikipedia.org/wiki/%E5%8D%8F%E7%A8%8B http ...

  8. 如鹏网仿QQ侧滑菜单:ResideMenu组件的使用笔记整理+Demo

    ResideMenu菜单 课堂笔记: https://github.com/SpecialCyCi/AndroidResideMenu Github:如何使用开源组件1. 下载 下载方式: 1. 项目 ...

  9. git合并分支到主干

    1.从当前分支切换主干 git checkout master 2.更新主干内容到本地 git pull 4.提交分支,并将分支merge到主干 git merge dev 5: i键后输入备注  输 ...

  10. 十三 Spring的通知类型,切入表达式写法

    Spring中通知类型: 前置通知:目标方法执行之前进行操作,可以获得切入点信息 后置通知: 目标方法执行之后进行操作,可以获得方法的返回值 环绕通知:在目标方法执行之前和之后进行操作,可以终止目标方 ...