1
0
mirror of https://github.com/chai2010/advanced-go-programming-book.git synced 2025-05-23 20:02:22 +00:00
This commit is contained in:
lewgun 2018-01-02 13:22:26 +08:00 committed by GitHub
parent 6531737f62
commit add8e13e1d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -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/ARMARM64等
## 你好, 世界! - V2.0
在经过半个世纪的涅槃重生之后Go语言不仅仅打印Unicode版本的“Hello, World”而且可以方便地向全球用户提供打印服务。下面版本通过`http`服务向每个访问的客户端打印中文的“你好, 世界!”和当前的时间信息。
在经过半个世纪的涅槃重生之后Go语言不仅仅打印出了Unicode版本的“Hello, World”而且可以方便地向全球用户提供打印服务。下面版本通过`http`服务向每个访问的客户端打印中文的“你好, 世界!”和当前的时间信息。
```go
package main