这几天看了《Go语言编程》这本书,在微博上吐了不少槽,得到了不少反馈,于是现在趁着新鲜记录一些简单的感受吧。

简单地说,这本书并不算好,至少相较于Go这门语言以及老许的技术水平来说,这本书着实写得一般。Go的确是一门有亮点的语言,尤其是相对C语言来说,例如其中的接口特性、“基于对象”的抽象方式、自然还有goroutine等一些被人广为了解的特色等等。不过问题关键在于,书中有些地方描述地太过火了,白白多出各种槽点。

以书中出现的顺序为准,随便摘录几个我还有印象的地方:

1、前言中关于defer关键字的描述:

在Java中,你可能这样写代码来保证资源正确释放:

Connection conn = ...;
try {
    Statement stmt = ...;
    try {
        ResultSet rset = ...;
        try {
            ... // 正常代码
        }
        finally {
            rset.close();
        }
    }
    finally {
        stmt.close();
    }
}
finally {
    conn.close();
}

完成同样的功能,相应的Go代码只需要写成这样:

conn := ...
defer conn.Close()

stmt := ...
defer stmt.Close()

rset := ...
defer rset.Close()

事实上,在如今的Java语言中,我们基本都是用try-with-resources特性来写这样的代码的:

try (Connection conn = ...;
     Statement stmt = ...;
     ResultSet rset = ...;) {

}

同时,对于defer关键字可以跟匿名函数的特点,其实对于支持匿名函数和闭包的语言来说,几乎都不成问题,也不失其优雅性。后面的章节还提到了recoverpanic,给人的感觉就是个普通的异常抛出和捕获机制,但是在那个地方却没有对这显而易见会出现的对比进行解释了。

2、第1章中关于多返回值的描述:

Go语言革命性地在静态开发语言阵营中率先提供了多返回值功能。

这种说法让ML系(SML、OCaml、F#)或Scala等语言情何以堪?更何况这个特性跟动态静态语言基本毫无关系,事实上都有人总结过这个问题,在搜索引擎上排名数一数二。

3、第2章中关于变量初始化的描述:

对于声明变量时需要进行初始化的场景,var关键字可以保留,但不再是必要的元素,如下所示:

var v1 int = 10 // 正确的使用方式1
var v2 = 10 // 正确的使用方式2,编译器可以自动推导出v2的类型
v3 := 10 // 正确的使用方式3,编译器可以自动推导出v3的类型

以上三种用法的效果是完全一样的(除了第三种声明方式不能用于声明全局变量)。与第一种用法相比,第三种用法需要输入的字符数大大减少,是懒程序员和聪明程序员的最佳选择。这里Go语言也引入了另一个C和C++中没有的符号(冒号和等号的组合:=),用于明确表达同时进行变量声明和初始化的工作。

说实话,这段描述,尤其是“懒程序员和聪明程序员的最佳选择”这种说法让我十分不满,在我看来,这不是硬把臭的说成香的么?多这么第三种方式有什么意义?难道就是因为省了三个字符?当然,事实上:=是有一定意义的,例如重新为之前声明过的变量赋值,或是直接在表达式内赋值并使用等等。尽管我觉得这个设计多余且有些自找麻烦,但这可以作为taste来讨论,远比书中“懒程序员和聪明程序员”要有意义地多。

此外,书中到处使用:=来创建局部变量,是否是一种误用?当然这是题外话。

4、第3章中关于“面向对象编程”的描述:

在Go语言中,面向对象的神秘面纱被剥得一干二净。对比下面的两段代码:

func (a Integer) Less(b Integer) bool { // 面向对象
    return a < b
}

func Integer_Less(a Integer, b Integer) bool { // 面向过程
    return a < b
}

a.Less(2) // 面向对象的用法
Integer_Less(a, 2) // 面向过程的用法

可以看出,面向对象只是换了一种语法形式来表达。C++语言的面向对象之所以让有些人迷惑的一大原因就在于其隐藏的this指针。一旦把隐藏的this指针显露出来,大家看到的就是一个面向过程编程。感兴趣的读者可以去查阅《深度探索C++对象模型》这本书,看看C++语言是如何对应到C语言的。而Java和C#其实都是遵循着C++语言的惯例而设计的,它们的成员方法中都带有一个隐藏的this指针。如果读者了解Python语法,就会知道Python的成员方法中会有一个self参数,它和this指针的作用是完全一样的。

我们对于一些事物的不理解或者畏惧,原因都在于这些事情所有意无意带有的绚丽外衣和神秘面纱。只要揭开这一层直达本质,就会发现一切其实都很简单。

上面这段话从“可以看出”开始就显得无厘头了一些,将编程范式和内部实现混在了一起。为什么Java的使用者要关注this是怎么传递的?这对于面向对象编程这种编程范式没有任何意义。这章最后还提到:

本章我们详细讲解了Go语言面向对象编程的相关特性。众多读者可能会有一个疑问,那就是与C++、Java和C#这些经典的面向对象语言相比,为什么只用了比第2章还短的篇幅就介绍完本章?是Go语言在面向对象编程上的支持力度不够,还是本书没有介绍完整呢?

在回答这个问题之前,读者可以先考虑一个问题:基于本章介绍的Go语言的面向对象编程特性,有C++、Java和C#可以实现而Go语言无法表达和实现的场景吗?事实上我们很难想出这种场景,也就是Go语言看似简陋的面向对象编程特性已经可以满足需求,这反而映射了其他语言在这方面可能做了过多的工作。用简单的语法、更少的代码就可以做完的事情,为什么我还要自 寻烦恼去学习繁复的语法,然后为众多实现细节而烦恼呢?

Go语言给我们开辟了一个新的视野,原来问题可以这么简单地解决。

其实我可以举出很多Java和C#中可以实现而Go语言无法表达的内容,但是我也可以自己按照“已经可以满足需求”来进行回应,但是这种应对方式是语言讨论中最没有意义的方式之一。Go语言的确提供了一种相对于Java和C#更为简单的数据抽象方式,也可能的确够用(这点我不会简单粗暴地反对),但因此说它实现了面向对象,能用来应对面向对象能实现的各种场景,这我表示看不下去。事实上,我不认为Go语言做到了面向对象(当然我也没说面向对象是必须的),它只不过是一种基于对象组合的方式来提供数据抽象能力(当然还有接口等等)。

印象中大部分的槽点都出现在本书的前半部分,描述Go语言基础能力的那些,而后半主要是围绕着类库和周边环境,所以没有太多可谈的地方。总体而言,这本书给我的印象,就好像在看一个Go语言粉丝,再竭力推销这门语言,但对于其中讲述内容的严肃性、正确性便有所放低了,这不是老许这一级别的人物应该给人的印象。这本书里很多地方对于Java和C#的批评并不是那么有道理(我又想起了在“并发编程”里的一段描述,但懒得举了)。

其实Go语言还是有所特色的,例如goroutine方面,尽管我认为它只是把其他一些语言/平台中用类库实现的功能做进了语言(有机会我会详述这一点),不过在语言级别强调一种编程方法/范式也是这种语言的文化,Erlang便是前例之一。可惜的是,书中只用了非常简短的篇幅描述了这个功能,但是对于它应该如何使用,如何以此来设计一个应用,如何进行架构规划,几乎可以说是只字未提。事实上,这方面通过一个稍微复杂点的案例也能较好地说明问题了,这在我之前看过的一本ManningProgmatic的Erlang书(具体哪本忘了)中就有体会。

假如要我给这本书打分(满分10分),我会打6分。只是再考虑到这本书在宣传时给人的印象,以及老许给人的期待,我只能给它打5分。假如有人问我学习Go语言是否该看这本书,我会建议他们去看Go语言的官方文档。其实老许和七牛在Go语言方面的积累绝对可以出一本好书,这本实在令人有些失望。

最后再说些有点关联又有些无关的话,好东西不需要太多修饰,多多描述就行了。不光是面向技术,还有其他方面。例如,不给牛人带高帽子他们就不是牛人了吗

评论

推荐 2
看着看着觉得有水平,看到最后发现是老赵,就难怪了。一直想研究Go,却一直无限期押后,还是得空看看Clojure好了。
是受《黑客和画家》的影响吧?Clojure 我在《七周七语言》中看过。 –  黄志斌 2013-04-08 06:51
嗯............... –  2gua 2013-04-08 08:35

推荐 1
没看过这本书,对书的内容不作评论。但看社区评论,似乎是一边倒的认为作者写得有问题;我又看了下当当的该书评价,读者的反馈显然并不像这里所说得那么糟糕。我想说,在没有更多参考资料的情况下,先有一本书,即使不是那么好,也比没有强。写这种书本就不赚钱,作者能拿出时间来做这样的工作,我认为是非常值得赞许和尊重的。有些人饿了,有热心人给蒸了锅馒头,旁边不饿的人啃了口:“这蒸的是馒头么,难吃死了。”还是那句话,写书的人和不写书的人的区别就是,后者始终优越地拥有对前者的批评权。
写书出来就是给人评价的,好书有人夸,差书有人批评,太正常不过了。再者说优越地批评权什么的,把作者和读者放在对立的位置上,实在不好。本来只是说书的内容,完全不谈态度是否赞许是否尊重,三两句话又跑到书外去了。 –  老赵 2013-04-09 00:58
赚不赚钱我不知道,但我是花了钱买的。七牛应该考虑开始扎实编写第二版了。 –  老黄 2013-04-09 08:48
第二版应该值得买吧,都那么久了,还没出呢? –  赵明威 2016-04-19 22:02

推荐 1
——例如goroutine方面,尽管我认为它只是把其他一些语言/平台中用类库实现的功能做进了语言(有机会我会详述这一点)
一般写有机会的时候,就是没机会了,老赵现在就写写吧,趁着热乎
嗯嗯,有道理…… –  老赵 2013-04-08 18:14

推荐 1
0. 这本书是“合著”的;
1. 这本书是在高压工作状态下挤出时间编写的。

看Rob Pike写的PPT可能更有感觉,我是这么入Golang的门的。
好吧,真不容易啊。不过我又想说了,审阅者哪里去了,推荐者哪里去了…… –  老赵 2013-04-08 14:30
老赵,应该说能写书,得有勇气有实力,毕竟第一本,还是要鼓励的,不信老赵你有天真想写的话,不知读者会不会拍死你。呵呵。 –  谢工在百度 2013-04-08 15:12
欢迎来拍,不过我肯定不会在内容上留下低级问题,最多可以说我写的难看组织不清收获不大嘿嘿……还有就是审校和推荐啊,我绝对会把握住的…… –  老赵 2013-04-08 16:18
要么写,要么不写,哪有那么多道理,本来总认为图灵书内容很不错的。 –  老黄 2013-04-08 17:34
很难说这本书是否达成写作初衷。我并不推荐这本。但多一个选择未必是坏事,也能引发更多人参与讨论。最后期待老赵出书。 –  梁涛 2013-04-08 23:29
不知道钝刀以前是否说过不推荐本书? –  2gua 2013-04-08 23:48
没说过。这本没看完,无法下结论。 –  梁涛 2013-04-08 23:56

推荐 1
我想翻译书因为有国外作者,国外出版社的层层把关,从策划选题开始,写作质量到产品设计都做足了功夫,我们引进时基本是现成品了,而原创技术书要完全从内容、结构和产品设计都要重构,出版社在专业书上的质量控制能力和参与度,目前看都是有限的。但不管怎样说,一本优秀的畅销书产生,需要强大的策划队伍、写作质量、产品设计包装等缺一不可,不是单靠一个人就能完成的,非常需要强大的团队支撑。

推荐 1
国内的技术原创图书,应该也建立专业技术人员审稿的机制,这样会让原创图书在专业品质方面有一定的保证和提升。但,国内有多少技术人员愿意在书出版之前,花费精力,给出如此专业的意见呢?
图灵有没有公开征人审稿? –  老赵 2013-04-08 18:16
图灵一直在尝试小范围内的技术审稿人的征集活动,并积累了一些资源。但还谈不上是一种机制。 –  旸谷 2013-04-09 08:07

推荐 1
看完这本书之后确实有同样的感受。其实就连Go的一些基本语法有的地方也是讲的语焉不详。:= 更像是c++11后的auto关键字,可以自动完成类型推导。不得不说的是,长年累月的用C/C++,忽然发现Go语言与自己的想法不谋而合是一种非常不错的体验。
自动推倒有var就是了,不需要:=的,我说的也是这个意思。 –  老赵 2013-04-08 00:14

推荐 0
一本讲新语言的书籍(如Learn Python),但整体的思路却是实用参考的路数(如Programming Python),最终,整体的阅读感觉也只能是一个普及读物的感觉,两边都没有深入,味如鸡肋!

推荐 0
也许就像大神说的那样 - Go 根本不是一个好语言。

推荐 0
支持,go确实是不错的语言,但是那本书作者吹得太露骨了。

我要评论

需要登录后才能发言
登录未成功,请修改提交。

相关图书

封面
Go语言编程