mirror of
https://github.com/chai2010/advanced-go-programming-book.git
synced 2025-05-24 12:32:21 +00:00
ch1.2: 规范化图和代码编号
This commit is contained in:
parent
59058a480c
commit
b03106c3c5
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
在创世纪章节中我们简单介绍了Go语言的演化基因族谱,对其中来自于贝尔实验室的特有并发编程基因做了重点介绍,最后引出了Go语言版的“Hello, World”程序。其实“Hello, World”程序是展示各种语言特性的最好的例子,是通向该语言的一个窗口。这一节我们将沿着各个编程语言演化的时间轴,简单回顾下“Hello, World”程序是如何逐步演化到目前的Go语言形式、最终完成它的革命使命的。
|
在创世纪章节中我们简单介绍了Go语言的演化基因族谱,对其中来自于贝尔实验室的特有并发编程基因做了重点介绍,最后引出了Go语言版的“Hello, World”程序。其实“Hello, World”程序是展示各种语言特性的最好的例子,是通向该语言的一个窗口。这一节我们将沿着各个编程语言演化的时间轴,简单回顾下“Hello, World”程序是如何逐步演化到目前的Go语言形式、最终完成它的革命使命的。
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
## 1.2.1 B语言 - Ken Thompson, 1972
|
## 1.2.1 B语言 - Ken Thompson, 1972
|
||||||
|
|
||||||
@ -10,6 +10,8 @@
|
|||||||
|
|
||||||
目前见到的B语言版本的“Hello World”,一般认为是来自于Brian W. Kernighan编写的B语言入门教程(Go核心代码库中的第一个提交者名字正是Brian W. Kernighan),程序如下:
|
目前见到的B语言版本的“Hello World”,一般认为是来自于Brian W. Kernighan编写的B语言入门教程(Go核心代码库中的第一个提交者名字正是Brian W. Kernighan),程序如下:
|
||||||
|
|
||||||
|
*代码 1.2-1*
|
||||||
|
|
||||||
```c
|
```c
|
||||||
main() {
|
main() {
|
||||||
extrn a, b, c;
|
extrn a, b, c;
|
||||||
@ -31,6 +33,8 @@ C语言是由Dennis Ritchie在B语言的基础上改进而来,它增加了丰
|
|||||||
|
|
||||||
在Brian W. Kernighan于1974年左右编写的C语言入门教程中,出现了第一个C语言版本的“Hello World”程序。这给后来大部分编程语言教程都以“Hello World”为第一个程序提供了惯例。第一个C语言版本的“Hello World”程序如下:
|
在Brian W. Kernighan于1974年左右编写的C语言入门教程中,出现了第一个C语言版本的“Hello World”程序。这给后来大部分编程语言教程都以“Hello World”为第一个程序提供了惯例。第一个C语言版本的“Hello World”程序如下:
|
||||||
|
|
||||||
|
*代码 1.2-2*
|
||||||
|
|
||||||
```c
|
```c
|
||||||
main()
|
main()
|
||||||
{
|
{
|
||||||
@ -42,6 +46,8 @@ main()
|
|||||||
|
|
||||||
这个例子同样出现在了1978年出版的《C程序设计语言》第一版中,作者正是Brian W. Kernighan 和 Dennis M. Ritchie(简称K&R)。书中的“Hello World”末尾增加了一个换行输出:
|
这个例子同样出现在了1978年出版的《C程序设计语言》第一版中,作者正是Brian W. Kernighan 和 Dennis M. Ritchie(简称K&R)。书中的“Hello World”末尾增加了一个换行输出:
|
||||||
|
|
||||||
|
*代码 1.2-3*
|
||||||
|
|
||||||
```c
|
```c
|
||||||
main()
|
main()
|
||||||
{
|
{
|
||||||
@ -53,6 +59,8 @@ main()
|
|||||||
|
|
||||||
在K&R的教程面世10年之后的1988年,《C程序设计语言》第二版终于出版了。此时ANSI C语言的标准化草案已经初步完成,但正式版本的文档尚未发布。不过书中的“Hello World”程序根据新的规范增加了`#include <stdio.h>`头文件包含语句,用于包含`printf`函数的声明(新的C89标准中,仅仅是针对`printf`函数而言,依然可以不用声明函数而直接使用)。
|
在K&R的教程面世10年之后的1988年,《C程序设计语言》第二版终于出版了。此时ANSI C语言的标准化草案已经初步完成,但正式版本的文档尚未发布。不过书中的“Hello World”程序根据新的规范增加了`#include <stdio.h>`头文件包含语句,用于包含`printf`函数的声明(新的C89标准中,仅仅是针对`printf`函数而言,依然可以不用声明函数而直接使用)。
|
||||||
|
|
||||||
|
*代码 1.2-4*
|
||||||
|
|
||||||
```c
|
```c
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
@ -64,6 +72,8 @@ main()
|
|||||||
|
|
||||||
然后到了1989年,ANSI C语言第一个国际标准发布,一般被称为C89。C89是流行最广泛的一个C语言标准,目前依然被大量使用。《C程序设计语言》第二版的也再次印刷新版本,并针对新发布的C89规范建议,给`main`函数的参数增加了`void`输入参数说明,表示没有输入参数的意思。
|
然后到了1989年,ANSI C语言第一个国际标准发布,一般被称为C89。C89是流行最广泛的一个C语言标准,目前依然被大量使用。《C程序设计语言》第二版的也再次印刷新版本,并针对新发布的C89规范建议,给`main`函数的参数增加了`void`输入参数说明,表示没有输入参数的意思。
|
||||||
|
|
||||||
|
*代码 1.2-5*
|
||||||
|
|
||||||
```c
|
```c
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
@ -82,6 +92,8 @@ Newsqueak是Rob Pike发明的老鼠语言的第二代,是他用于实践CSP并
|
|||||||
|
|
||||||
Newsqueak类似脚本语言,内置了一个`print`函数,它的“Hello World”程序看不出什么特色:
|
Newsqueak类似脚本语言,内置了一个`print`函数,它的“Hello World”程序看不出什么特色:
|
||||||
|
|
||||||
|
*代码 1.2-6*
|
||||||
|
|
||||||
```go
|
```go
|
||||||
print("Hello,", "World", "\n");
|
print("Hello,", "World", "\n");
|
||||||
```
|
```
|
||||||
@ -92,6 +104,8 @@ print("Hello,", "World", "\n");
|
|||||||
|
|
||||||
Newsqueak语言并发版本的“素数筛”程序如下:
|
Newsqueak语言并发版本的“素数筛”程序如下:
|
||||||
|
|
||||||
|
*代码 1.2-7*
|
||||||
|
|
||||||
```go
|
```go
|
||||||
// 向管道输出从2开始的自然数序列
|
// 向管道输出从2开始的自然数序列
|
||||||
counter := prog(c:chan of int) {
|
counter := prog(c:chan of int) {
|
||||||
@ -150,6 +164,8 @@ Newsqueak语言中并发体和管道的语法和Go语言已经比较接近了,
|
|||||||
|
|
||||||
Alef语言并发版本的“Hello World”程序如下:
|
Alef语言并发版本的“Hello World”程序如下:
|
||||||
|
|
||||||
|
*代码 1.2-8*
|
||||||
|
|
||||||
```c
|
```c
|
||||||
#include <alef.h>
|
#include <alef.h>
|
||||||
|
|
||||||
@ -182,6 +198,9 @@ Limbo(地狱)是用于开发运行在小型计算机上的分布式应用的
|
|||||||
|
|
||||||
Limbo语言版本的“Hello World”程序如下:
|
Limbo语言版本的“Hello World”程序如下:
|
||||||
|
|
||||||
|
|
||||||
|
*代码 1.2-9*
|
||||||
|
|
||||||
```go
|
```go
|
||||||
implement Hello;
|
implement Hello;
|
||||||
|
|
||||||
@ -208,6 +227,8 @@ init(ctxt: ref Draw->Context, args: list of string)
|
|||||||
|
|
||||||
### 1.2.6.1 hello.go - 2008年6月
|
### 1.2.6.1 hello.go - 2008年6月
|
||||||
|
|
||||||
|
*代码 1.2-10*
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
|
|
||||||
@ -221,6 +242,8 @@ func main() int {
|
|||||||
|
|
||||||
### 1.2.6.2 hello.go - 2008年6月27日
|
### 1.2.6.2 hello.go - 2008年6月27日
|
||||||
|
|
||||||
|
*代码 1.2-11*
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
|
|
||||||
@ -233,6 +256,8 @@ func main() {
|
|||||||
|
|
||||||
### 1.2.6.3 hello.go - 2008年8月11日
|
### 1.2.6.3 hello.go - 2008年8月11日
|
||||||
|
|
||||||
|
*代码 1.2-12*
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
|
|
||||||
@ -245,6 +270,8 @@ func main() {
|
|||||||
|
|
||||||
### 1.2.6.4 hello.go - 2008年10月24日
|
### 1.2.6.4 hello.go - 2008年10月24日
|
||||||
|
|
||||||
|
*代码 1.2-13*
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
|
|
||||||
@ -259,6 +286,8 @@ func main() {
|
|||||||
|
|
||||||
### 1.2.6.5 hello.go - 2009年1月15日
|
### 1.2.6.5 hello.go - 2009年1月15日
|
||||||
|
|
||||||
|
*代码 1.2-14*
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
|
|
||||||
@ -273,6 +302,8 @@ Go语言开始采用是否大小写首字母来区分符号是否可以被导出
|
|||||||
|
|
||||||
### 1.2.6.7 hello.go - 2009年12月11日
|
### 1.2.6.7 hello.go - 2009年12月11日
|
||||||
|
|
||||||
|
*代码 1.2-15*
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
|
|
||||||
@ -290,6 +321,8 @@ Go语言终于移除了语句末尾的分号。这是Go语言在2009年11月10
|
|||||||
|
|
||||||
在经过半个世纪的涅槃重生之后,Go语言不仅仅打印出了Unicode版本的“Hello, World”,而且可以方便地向全球用户提供打印服务。下面版本通过`http`服务向每个访问的客户端打印中文的“你好, 世界!”和当前的时间信息。
|
在经过半个世纪的涅槃重生之后,Go语言不仅仅打印出了Unicode版本的“Hello, World”,而且可以方便地向全球用户提供打印服务。下面版本通过`http`服务向每个访问的客户端打印中文的“你好, 世界!”和当前的时间信息。
|
||||||
|
|
||||||
|
*代码 1.2-16*
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
|
|
||||||
|
BIN
images/ch1.2-1-go-history.png
Normal file
BIN
images/ch1.2-1-go-history.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 9.5 KiB |
2
vendor/ch1.1-1/doc_ch1-01.go
vendored
2
vendor/ch1.1-1/doc_ch1-01.go
vendored
@ -1,2 +0,0 @@
|
|||||||
// ch1-01/01
|
|
||||||
package main
|
|
2
vendor/ch1.1-1/main.go
vendored
2
vendor/ch1.1-1/main.go
vendored
@ -1,3 +1,5 @@
|
|||||||
|
// ch1.1-1
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import "fmt"
|
import "fmt"
|
||||||
|
10
vendor/ch1.2-1/hello.b
vendored
Normal file
10
vendor/ch1.2-1/hello.b
vendored
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
// ch1.2-1
|
||||||
|
|
||||||
|
main() {
|
||||||
|
extrn a, b, c;
|
||||||
|
putchar(a); putchar(b); putchar(c);
|
||||||
|
putchar('!*n');
|
||||||
|
}
|
||||||
|
a 'hell';
|
||||||
|
b 'o, w';
|
||||||
|
c 'orld';
|
10
vendor/ch1.2-10/hello.go
vendored
Normal file
10
vendor/ch1.2-10/hello.go
vendored
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
// ch1.2-10
|
||||||
|
|
||||||
|
// +build ignore
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
func main() int {
|
||||||
|
print "hello, world\n";
|
||||||
|
return 0;
|
||||||
|
}
|
9
vendor/ch1.2-11/hello.go
vendored
Normal file
9
vendor/ch1.2-11/hello.go
vendored
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
// ch1.2-11
|
||||||
|
|
||||||
|
// +build ignore
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
print "hello, world\n";
|
||||||
|
}
|
7
vendor/ch1.2-12/hello.go
vendored
Normal file
7
vendor/ch1.2-12/hello.go
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
// ch1.2-12
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
print("hello, world\n")
|
||||||
|
}
|
11
vendor/ch1.2-13/hello.go
vendored
Normal file
11
vendor/ch1.2-13/hello.go
vendored
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
// ch1.2-13
|
||||||
|
|
||||||
|
// +build ignore
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
fmt.printf("hello, world\n")
|
||||||
|
}
|
11
vendor/ch1.2-14/hello.go
vendored
Normal file
11
vendor/ch1.2-14/hello.go
vendored
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
// ch1.2-14
|
||||||
|
|
||||||
|
// +build ignore
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
fmt.Printf("hello, world\n") // ;
|
||||||
|
}
|
9
vendor/ch1.2-15/hello.go
vendored
Normal file
9
vendor/ch1.2-15/hello.go
vendored
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
// ch1.2-15
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
fmt.Printf("hello, world\n")
|
||||||
|
}
|
22
vendor/ch1.2-16/main.go
vendored
Normal file
22
vendor/ch1.2-16/main.go
vendored
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
// 1.2-16
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
fmt.Println("Please visit http://127.0.0.1:12345/")
|
||||||
|
http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
|
||||||
|
s := fmt.Sprintf("你好, 世界! -- Time: %s", time.Now().String())
|
||||||
|
fmt.Fprintf(w, "%v\n", s)
|
||||||
|
log.Printf("%v\n", s)
|
||||||
|
})
|
||||||
|
if err := http.ListenAndServe(":12345", nil); err != nil {
|
||||||
|
log.Fatal("ListenAndServe: ", err)
|
||||||
|
}
|
||||||
|
}
|
6
vendor/ch1.2-2/hello.c
vendored
Normal file
6
vendor/ch1.2-2/hello.c
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
// ch1.2-2
|
||||||
|
|
||||||
|
main()
|
||||||
|
{
|
||||||
|
printf("hello, world");
|
||||||
|
}
|
6
vendor/ch1.2-3/hello.c
vendored
Normal file
6
vendor/ch1.2-3/hello.c
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
// ch1.2-3
|
||||||
|
|
||||||
|
main()
|
||||||
|
{
|
||||||
|
printf("hello, world\n");
|
||||||
|
}
|
8
vendor/ch1.2-4/hello.c
vendored
Normal file
8
vendor/ch1.2-4/hello.c
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
// ch1.2-4
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
main()
|
||||||
|
{
|
||||||
|
printf("hello, world\n");
|
||||||
|
}
|
8
vendor/ch1.2-5/hello.c
vendored
Normal file
8
vendor/ch1.2-5/hello.c
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
// ch1.2-5
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
main(void)
|
||||||
|
{
|
||||||
|
printf("hello, world\n");
|
||||||
|
}
|
3
vendor/ch1.2-6/hello.newsqueak
vendored
Normal file
3
vendor/ch1.2-6/hello.newsqueak
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
// ch1.2-6
|
||||||
|
|
||||||
|
print("Hello,", "World", "\n");
|
43
vendor/ch1.2-7/prime.newsqueak
vendored
Normal file
43
vendor/ch1.2-7/prime.newsqueak
vendored
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
// ch1.2-7
|
||||||
|
|
||||||
|
// 向管道输出从2开始的自然数序列
|
||||||
|
counter := prog(c:chan of int) {
|
||||||
|
i := 2;
|
||||||
|
for(;;) {
|
||||||
|
c <-= i++;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 针对listen管道获取的数列,过滤掉是prime倍数的数
|
||||||
|
// 新的序列输出到send管道
|
||||||
|
filter := prog(prime:int, listen, send:chan of int) {
|
||||||
|
i:int;
|
||||||
|
for(;;) {
|
||||||
|
if((i = <-listen)%prime) {
|
||||||
|
send <-= i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 主函数
|
||||||
|
// 每个管道第一个流出的数必然是素数
|
||||||
|
// 然后基于这个新的素数构建新的素数过滤器
|
||||||
|
sieve := prog() of chan of int {
|
||||||
|
c := mk(chan of int);
|
||||||
|
begin counter(c);
|
||||||
|
prime := mk(chan of int);
|
||||||
|
begin prog(){
|
||||||
|
p:int;
|
||||||
|
newc:chan of int;
|
||||||
|
for(;;){
|
||||||
|
prime <-= p =<- c;
|
||||||
|
newc = mk();
|
||||||
|
begin filter(p, c, newc);
|
||||||
|
c = newc;
|
||||||
|
}
|
||||||
|
}();
|
||||||
|
become prime;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 启动素数筛
|
||||||
|
prime := sieve();
|
21
vendor/ch1.2-8/hello.alef
vendored
Normal file
21
vendor/ch1.2-8/hello.alef
vendored
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
// ch1.2-8
|
||||||
|
|
||||||
|
#include <alef.h>
|
||||||
|
|
||||||
|
void receive(chan(byte*) c) {
|
||||||
|
byte *s;
|
||||||
|
s = <- c;
|
||||||
|
print("%s\n", s);
|
||||||
|
terminate(nil);
|
||||||
|
}
|
||||||
|
|
||||||
|
void main(void) {
|
||||||
|
chan(byte*) c;
|
||||||
|
alloc c;
|
||||||
|
proc receive(c);
|
||||||
|
task receive(c);
|
||||||
|
c <- = "hello proc or task";
|
||||||
|
c <- = "hello proc or task";
|
||||||
|
print("done\n");
|
||||||
|
terminate(nil);
|
||||||
|
}
|
17
vendor/ch1.2-9/hello.limbo
vendored
Normal file
17
vendor/ch1.2-9/hello.limbo
vendored
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
// ch1.2-9
|
||||||
|
|
||||||
|
implement Hello;
|
||||||
|
|
||||||
|
include "sys.m"; sys: Sys;
|
||||||
|
include "draw.m";
|
||||||
|
|
||||||
|
Hello: module
|
||||||
|
{
|
||||||
|
init: fn(ctxt: ref Draw->Context, args: list of string);
|
||||||
|
};
|
||||||
|
|
||||||
|
init(ctxt: ref Draw->Context, args: list of string)
|
||||||
|
{
|
||||||
|
sys = load Sys Sys->PATH;
|
||||||
|
sys->print("hello, world\n");
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user