diff --git a/ch1-basic/ch1-02-hello-revolution.md b/ch1-basic/ch1-02-hello-revolution.md index 9b5a5ad..fb2b3cf 100644 --- a/ch1-basic/ch1-02-hello-revolution.md +++ b/ch1-basic/ch1-02-hello-revolution.md @@ -1,14 +1,14 @@ # 1.2. Hello, World 的革命 -在创世纪章节中我们简单介绍了Go语言的演化基因族谱,对其中来自贝尔实验室特有并发编程基因做了重点介绍,最后引出了Go语言版的“Hello, World”程序。其实“Hello, World”程序是展示各种语言特性的最好的例子,是通向该语言的一个窗口。这一节我们就沿着各个编程语言演化的时间轴,简单回顾下“Hello, World”程序是如何逐步演化到目前的Go语言形式、最终完成“Hello, World”革命使命的。 - +在创世纪章节中我们简单介绍了Go语言的演化基因族谱,对其中来自于贝尔实验室的特有并发编程基因做了重点介绍,最后引出了Go语言版的“Hello, World”程序。其实“Hello, World”程序是展示各种语言特性的最好的例子,是通向该语言的一个窗口。这一节我们将沿着各个编程语言演化的时间轴,简单回顾下“Hello, World”程序是如何逐步演化到目前的Go语言形式、最终完成它的革命使命的。 + ![](../images/ch1-01-go-history.png) ## B语言 - Ken Thompson, 1972 -首先是B语言,B语言是Go语言之父贝尔实验室的Ken Thompson早年间开发的一种通用的程序设计语言,设计目的是为了用于辅助UNIX系统的开发。但是因为B语言缺乏灵活的类型系统导致使用比较困难。后来,Ken Thompson的同事丹尼斯·利奇以B语言为基础开发出C语言,C语言因为提供了丰富的类型,极大地增加了语言的表达能力。目前C语言依然是世界上最常用的程序语言之一。自从被C语言取代之后,B语言就已经成为了历史只存在于各种文献之中了。 +首先是B语言,B语言是Go语言之父贝尔实验室的Ken Thompson早年间开发的一种通用的程序设计语言,设计目的是为了用于辅助UNIX系统的开发。但是因为B语言缺乏灵活的类型系统导致使用比较困难。后来,Ken Thompson的同事Dennis Ritchie以B语言为基础开发出了C语言,C语言提供了丰富的类型,极大地增加了语言的表达能力。到目前为止它依然是世界上最常用的程序语言之一。而B语言自从被它取代之后,则就只存在于各种文献之中,成为了历史。 -目前,见到的B语言版本的“Hello World”一般认为是来自于Brian W. Kernighan编写的B语言入门教程(Go核心代码库中的第一个提交者名字正是Brian W. Kernighan),程序如下: +目前见到的B语言版本的“Hello World”,一般认为是来自于Brian W. Kernighan编写的B语言入门教程(Go核心代码库中的第一个提交者名字正是Brian W. Kernighan),程序如下: ```c main() { @@ -21,13 +21,13 @@ b 'o, w'; c 'orld'; ``` -由于B语言缺乏灵活的数据类型,只能分别以`a/b/c`全局变量来定义要输出的内容,并且每个变量的长度必须对齐到了4个字节(有一种写汇编语言的感觉)。然后通过多次调用`putchar`函数输出字符,最后一个`'!*n'`表示输出一个换行的意思。 +由于B语言缺乏灵活的数据类型,只能分别以`a/b/c`全局变量来定义要输出的内容,并且每个变量的长度必须对齐到了4个字节(有一种写汇编语言的感觉)。然后通过多次调用`putchar`函数输出字符,最后的`'!*n'`表示输出一个换行的意思。 -总体来说,B语言虽然简单,但是程序的功能也比较简陋。 +总体来说,B语言简单,功能也比较简陋。 ## C语言 - Dennis Ritchie, 1974 ~ 1989 -C语言是由Dennis Ritchie在B语言的基础上改进而来,C语言增加了丰富的数据类型,并最终实现了用C语言重写UNIX的伟大目标。C语言可以说是现代IT行业最重要的软件基石,目前最主流的操作系统几乎全部是由C语言开发的,许多基础系统软件也是C语言开发的。C系家族的编程语言占据统治地位达几十年之久,半个多世纪以来依然充满活力。 +C语言是由Dennis Ritchie在B语言的基础上改进而来,它增加了丰富的数据类型,并最终实现了用它重写UNIX的伟大目标。C语言可以说是现代IT行业最重要的软件基石,目前主流的操作系统几乎全部是由C语言开发的,许多基础系统软件也是C语言开发的。C系家族的编程语言占据统治地位达几十年之久,半个多世纪以来依然充满活力。 在Brian W. Kernighan于1974年左右编写的C语言入门教程中,出现了第一个C语言版本的“Hello World”程序。这给后来大部分编程语言教程都以“Hello World”为第一个程序提供了惯例。第一个C语言版本的“Hello World”程序如下: @@ -38,7 +38,7 @@ main() } ``` -关于这个程序,有几点需要说明的:首先是`main`函数因为没有明确返回值类型,默认返回`int`类型;其次`printf`函数默认不需要导入函数声明即可以使用;最后`main`没有明确返回语句也默认返回0值。在这个程序出现时,C语言还远未标准化,我们看到的是上古时代的C语言语法:函数不用写返回值,函数参数也可以忽略,使用printf时不需要包含头文件等。 +关于这个程序,有几点需要说明的:首先是`main`函数因为没有明确返回值类型,默认返回`int`类型;其次`printf`函数默认不需要导入函数声明即可以使用;最后`main`没有明确返回语句,但默认返回0值。在这个程序出现时,C语言还远未标准化,我们看到的是上古时代的C语言语法:函数不用写返回值,函数参数也可以忽略,使用printf时不需要包含头文件等。 这个例子同样出现在了1978年出版的《C程序设计语言》第一版中,作者正是Brian W. Kernighan 和 Dennis M. Ritchie(简称K&R)。书中的“Hello World”末尾增加了一个换行输出: @@ -204,7 +204,7 @@ init(ctxt: ref Draw->Context, args: list of string) ## Go语言 - 2007~2009 -贝尔实验室后来经历了多次动荡,包括Ken Thompson在内的Plan9项目原班人马最终加入了Google公司。在发明Limbo等前辈语言诞生10多年之后,在2007年底,Go语言三个最初作者因为偶然的因素聚集到一起批斗C++(传说是C++语言的布道师在Google公司到处鼓吹的C++11各种牛逼特性彻底惹恼了他们),他们终于抽出了20%的自由时间创造了Go语言。最初的Go语言规范从2008年3月开始编写,最初的Go程序也是直接编译到C语言然后再二次编译为机器码。到了2008年5月,Google公司的领导们终于发现了Go语言的巨大潜力,从而开始全力支持这个项目(Google的创始人甚至还贡献了`func`关键字),让他们可以将全部工作时间投入到Go语言的设计和开发中。在Go语言规范初版完成之后,Go语言的编译器终于可以直接生成机器码了。 +贝尔实验室后来经历了多次动荡,包括Ken Thompson在内的Plan9项目原班人马最终加入了Google公司。在发明Limbo等前辈语言诞生10多年之后,在2007年底,Go语言三个最初的作者因为偶然的因素聚集到一起批斗C++(传说是C++语言的布道师在Google公司到处鼓吹的C++11各种牛逼特性彻底惹恼了他们),他们终于抽出了20%的自由时间创造了Go语言。最初的Go语言规范从2008年3月开始编写,最初的Go程序也是直接编译到C语言然后再二次编译为机器码。到了2008年5月,Google公司的领导们终于发现了Go语言的巨大潜力,从而开始全力支持这个项目(Google的创始人甚至还贡献了`func`关键字),让他们可以将全部工作时间投入到Go语言的设计和开发中。在Go语言规范初版完成之后,Go语言的编译器终于可以直接生成机器码了。 ### hello.go - 2008年6月 @@ -269,7 +269,7 @@ func main() { } ``` -Go语言开始采用首字母的大小写来区分是否为导出符号。大写字母开头表示导出的公共符号,小写字母开头表示包内部的私有符号。国内用户需要注意的是,汉字中没有大小写字母的概念,因此以汉字开头的符号目前是无法导出的(针对问题中国用户已经给出相关建议,等Go2之后或许会调整对汉字的导出规则)。 +Go语言开始采用是否大小写首字母来区分符号是否可以被导出。大写字母开头表示导出的公共符号,小写字母开头表示包内部的私有符号。国内用户需要注意的是,汉字中没有大小写字母的概念,因此以汉字开头的符号目前是无法导出的(针对问题中国用户已经给出相关建议,等Go2之后或许会调整对汉字的导出规则)。 ### hello.go - 2009年12月11日 @@ -307,7 +307,7 @@ func main() { 先通过`C.CString`函数将Go语言字符串转为C语言字符串,然后调用C语言的`C.fputs`函数向标准输出窗口打印转换后的C字符串。`defer`延迟语句保证程序返回前通过`C.free`释放分配的C字符串。需要注意的是, CGO不支持C语言中的可变参数函数(因为Go语言每次函数调用的栈帧大小是固定的,而且Go语言中可变参数语法只是切片的一个语法糖而已),因此在Go语言中是无法通过CGO访问C语言的`printf`等可变参数函数的。同时,CGO只能访问C语言的函数、变量和简单的宏定义常量,CGO并不支持访问C++语言的符号(C++和C语言符号的名字修饰规则不同,CGO采用C语言的名字修饰规则)。 -其实CGO不仅仅用于Go语言中调用C语言函数,还可以用于导出Go语言函数给C语言函数调用。在用Go语言编写生成C静态库或C动态库时,也可以用CGO导出对应的接口函数。正是CGO的存在,才保证了Go语言和C语言资源的双向互通,同时保证了Go语言可以继承C语言已有的庞大的软件资产。 +其实CGO不仅仅用于在Go语言中调用C语言函数,还可以用于导出Go语言函数给C语言函数调用。在用Go语言编写生成C语言的静、动态库时,也可以用CGO导出对应的接口函数。正是CGO的存在,才保证了Go语言和C语言资源的双向互通,同时保证了Go语言可以继承C语言已有的庞大的软件资产。 ## SWIG版本 @@ -391,7 +391,7 @@ Go汇编语言虽然针对每种CPU架构(主要有386/AMD64/ARM/ARM64等) ## 你好, 世界! - V2.0 -在经过半个世纪的涅槃重生之后,Go语言不仅仅打印Unicode版本的“Hello, World”,而且可以方便地向全球用户提供打印服务。下面版本通过`http`服务向每个访问的客户端打印中文的“你好, 世界!”和当前的时间信息。 +在经过半个世纪的涅槃重生之后,Go语言不仅仅打印出了Unicode版本的“Hello, World”,而且可以方便地向全球用户提供打印服务。下面版本通过`http`服务向每个访问的客户端打印中文的“你好, 世界!”和当前的时间信息。 ```go package main