标签 Google 下的文章

为什么不用用Go?

本文翻译自 Dr. Dobb's主编Andrew Binstock的文章"Why Not Go?"。

Go是一种对系统原生语言的重要反思,它对C语言做了重大的改善,同时还保持了语言的极简性。

今年早些时候,我们写了一篇有关新兴系统原生(native)语言的文章。这些语言包括D、Go、Rust以及Vala。当时我们承诺将会对这些语言进行 细致的探索。从本周开始,我们将开启一系列对来自Google的新语言Go的探索之旅,该系列共有五部分。不同于以往Dr.Dobb's的教程系列,我们 会在连续的几周内发表这些文章,这样你就可以及时且更快的了解到这门语言了。

与这个列表上的其他语言相比,Go语言对我更加有吸引力。虽然我不是Go语言专家,但我喜欢到目前为止我看到的有关Go的一切。正如你所见到的,我的愉悦 来自于对完备的语言特性选择的欣赏,而不是新语言首次亮相所带来的那种热情(我承认我也很容易受到这种兴奋带来的影响 – 这就是为什么我能识别出与喜欢Go的原因的不同之处)。下面这些特性对我尤其有吸引力:

简单而快捷的编译。Go语言编译速度很快。事实上,它的编译速度如此之快,可以轻松地被当作脚本语言使用。编译速度这么快的几个原因包括它 没有使用头文件;如果一个模块依赖A,而A依赖B,那么当A中发生一个改变时,只需要重新编译A原模块以及A的依赖即可;最后一点,目标模块包含了足够的 依赖信息,这样编译器不再需要make文件。你只需简单地进行主模块的编译,它就会自动编译工程中的所有需要被更新的模块。这是不是很酷呢?

通过多个返回值的错误处理。现今在系统原生语言中有两类主要的错误处理范式:类似C中的返回值,或类似OO语言中的异常。这两种范式都不那 么理想。但在这两者之中,返回值范式更加让人沮丧,因为返回的错误码经常与从函数中返回的其他数据相冲突。Go通过允许函数返回多个值的方式解决了这个问 题。你可以指定一个从函数返回的值代表类型错误,并可以在任意函数返回的时刻对其进行检查。如果你不关心这个错误值,你可以不检查它。无论哪种情况,函数 的常规返回值都可供你使用。

简化的组合(而不是继承)。就像在Java中那样,通过使用interface指定行为,类型可以作为对象的成员。例如,标准库中的io包 定义了一个Writer,该接口指定了一个方法:一个Write函数,以字符数组作为输入参数,返回整型值和错误类型。任何实现了与这个Write方法签 名相同的类型都是io.Writer接口的一个事实上的实现。这个设计优雅地解除了代码中的耦合。它同时也简化了单元测试mock对象的实现。例如,如 果你想要测试一个Database对象中的方法,在标准语言中你需要创建一个Database对象来创建mock,这个对象需要大量初始化和协议实现工 作。在Go语言中,如果这个被测试的方法实现了某个interface,那么你可以使用这个接口创建任意对象,用起来很方便。这样你就可以创建 MockDatabase,它是一个最小对象,仅需实现一些必要的方法以使用这个需要被mock的interface – 无需构造函数,无需新增特性,只要方法。

简化的并发。在Go中并发相当的容易。将关键字'go'放在任意函数前面,这个函数就会在其自己的go-routine(一个非常轻量的线 程)里面运行。Go-routine之间通过channel通信,channel在本质上是一种阻塞消息队列。常见的互斥工具在Go中都具备,但Go语言 通过启动并发任务以及通过channel协作的方式简化了这类操作。

非常棒的错误消息。在我见过的语言中没有哪门语言在输出诊断信息方面能与Go想媲美。例如,如果一个程序死锁了,Go运行时会通知你,甚至可以达到告诉你哪个线程导致这次死锁的程度。编译器输出的错误信息也十分详细和有用。

大杂烩:Go语言还有其他极具吸引力的特性,这里带大家快速浏览一遍:高阶函数,垃圾收集,hashmap以及内置到语言(语言语法的一部分,不是通过库引入的)中的可扩展的数组。

当然,不是所有东西都是彩虹棒棒糖。这个工具仍然不成熟,开发社区规模也很小,但有Google这样的公司作为Go语言的后盾,这两方面不足肯定会被弥补 的。许多语言 – 尤其是D、Dust以及Vala,致力于简化C++以及增加特定特性,这让我感觉它们更像是"带有更好特性的C++",而Go语言,其设计内涵中有一种对 系统原生语言要如何运转的重要的反思。正是出于这种认识,一个去除了许多问题的优雅实现诞生了。即使你没有什么特别的需求考虑去使用Go语言,那么我认为 用你最直接的方式去了解这门语言,你会发现Go的许多特性会让你赏心悦目。Cheers!

buildc 0.1.9版本发布

随着buildc使用的深入,越来越多的新需求暴露了出来。为了满足这些需求,我们组的小兄弟又对buildc进行了一些改造,这些变化如下:

1、支持将多个子工程打包到一个安装包中

最初buildc的设计思想是为每个子工程单独制作安装包,这样具有很强的灵活性。但在对现有N个工程进行构建脚本改造的过程中发现,有些工程间存在严重 依赖,比如工程A是一个业务级公共库工程,工程B和工程C都依赖工程A构建后生成的静态共享库。而工程A又无法被当成第三方库处理,这给我们的安装包构建 制造了难题。我们的解决方法就是改造安装包工程的setup.cfg文件,让其支持多source。从正规语义上来讲,我们这么做将使得buildc支持 将多个子工程打包到一个安装包中,而间接的作用则是解决了上述有依赖关系的工程安装包制作的问题,虽然看起来不那么美。

修改后,setup.cfg中配置就变成下面这种情况了:

source = [
  {
     "trunk"          : "svn://10.10.15.56:4444/cn/trunk/A",
     "binary_prefix"  : "fooA"
  },

  {
    "trunk"          : "svn://10.10.15.56:4444/cn/trunk/B",
    "binary_prefix"  : "fooB"
  }
]

不过问题并没有彻底解决。A工程的构建结果是一个.a文件,按照原buildc处理流程,该.a文件会被放入安装包中的app目录下,但这不是我们想要 的,.a文件是不应该放入安装包的。与此同时,一些子工程的输出是.so文件,按照最初的规划,这些.so文件应该被放入deps目录,而原buildc 默认都是放在app目录下。为了解决这个问题,我们给source做了"属性扩容" – 增加了一个可选的pack_path字段。

source = [
  {
     "trunk"          : "svn://10.10.15.56:4444/cn/trunk/A",
     "binary_prefix"  : "fooA"
     "pack_path" : ""
  },

  {
    "trunk"          : "svn://10.10.15.56:4444/cn/trunk/B",
    "binary_prefix"  : "fooB"
  },

  {
    "trunk"          : "svn://10.10.15.56:4444/cn/trunk/C",
    "binary_prefix"  : "fooC"
    "pack_path" : "deps"
  }
]

这个示例中,A工程pack_path的值为"",buildc将忽略A工程的输出文件,B工程没有配置pack_path,则buildc默认将B工程 的输出文件放入app目录;而C工程明确为pack_path赋了值,buildc会将C工程输出文件放入deps目录。

buildc原本支持在命令行输入工程源码库地址(–tag=YOUR_SOURCE_TAG),现在依旧支持。一旦命令行指定了工程地 址,buildc将不会理睬setup.cfg中source中配置的各个源码库路径,将从命令行指定的工程地址处取得最新源码,但暂无法指定 pack_path,默认会将构建结果放入app目录。

2、打包时自动生成VERSION文件

buildc在执行pack build后,自动在安装包中生成一个VERSION文件。该文件中包含与安装包匹配的平台信息(包括CPU体系、OS类型等)以及构建时的一些版本信 息。该文件除了便于安装包使用人员查看安装包相关版本信息之外,还可以用作安装包在目标平台进行约束检测的依据。如果你的安装包是for x86-64 linux的,那么宕操作人员误将该安装包部署到Solaris 10 for sparc平台时,安装包中的deps_check.py脚本会比对当前平台信息与VERSION文件中携带的信息,发现不匹配,则报错并停止程序的安 装。

3、其他

该版本buildc还提供了一些脚本的详细示例,如env_gen.py、deps_check.py。另外从Make.rules.in模板中去除了硬编码的-D_DEBUG定义。

如发现本站页面被黑,比如:挂载广告、挖矿等恶意代码,请朋友们及时联系我。十分感谢! Go语言第一课 Go语言进阶课 AI原生开发工作流实战 Go语言精进之路1 Go语言精进之路2 Go语言第一课 Go语言编程指南
商务合作请联系bigwhite.cn AT aliyun.com

欢迎使用邮件订阅我的博客

输入邮箱订阅本站,只要有新文章发布,就会第一时间发送邮件通知你哦!

这里是 Tony Bai的个人Blog,欢迎访问、订阅和留言! 订阅Feed请点击上面图片

如果您觉得这里的文章对您有帮助,请扫描上方二维码进行捐赠 ,加油后的Tony Bai将会为您呈现更多精彩的文章,谢谢!

如果您希望通过微信捐赠,请用微信客户端扫描下方赞赏码:

如果您希望通过比特币或以太币捐赠,可以扫描下方二维码:

比特币:

以太币:

如果您喜欢通过微信浏览本站内容,可以扫描下方二维码,订阅本站官方微信订阅号“iamtonybai”;点击二维码,可直达本人官方微博主页^_^:
本站Powered by Digital Ocean VPS。
选择Digital Ocean VPS主机,即可获得10美元现金充值,可 免费使用两个月哟! 著名主机提供商Linode 10$优惠码:linode10,在 这里注册即可免费获 得。阿里云推荐码: 1WFZ0V立享9折!


View Tony Bai's profile on LinkedIn
DigitalOcean Referral Badge

文章

评论

  • 正在加载...

分类

标签

归档



View My Stats