Go 语言的演化历程_第1页
Go 语言的演化历程_第2页
Go 语言的演化历程_第3页
Go 语言的演化历程_第4页
Go 语言的演化历程_第5页
已阅读5页,还剩14页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、Go 语言的演化历程2014-10-31 09:48 oschina 开源中国社区 字号:T | T本文来自Google的Golang语言设计者之一Rob Pike大神在GopherCon2014大会上的开幕主题演讲资料“Hello, Gophers!”。Rob大神在这次分 享中用了两个生动的例子讲述了Golang的演化历程,总结了Golang到目前为止的成功因素,值得广大Golang Programmer & Beginner学习和了解。这里也用了”Golang的演化历程”作为标题。AD: 2014WOT全球软件技术峰会北京站 课程视频发布 11月21日-22日 与WOT技术大会相约深圳 现

2、在抢票 本文来自Google的Golang语言设计者之一Rob Pike大神在GopherCon2014大会上的开幕主题演讲资料“Hello, Gophers!”。Rob大神在这次分 享中用了两个生动的例子讲述了Golang的演化历程,总结了Golang到目前为止的成功因素,值得广大Golang Programmer & Beginner学习和了解。这里也用了”Golang的演化历程”作为标题。1、Hello Gophers!1. packagemain2. 3. importfmt4. 5. funcmain()6. fmt.Printf(Hello,gophers!n)7. Rob大神的见

3、面礼,后续会有针对这段的演化历史的陈述。2、历史这是一个历史性的时刻。Golang已经获得了一定的成功,值得拥有属于自己的技术大会。3、成功促成这份成功的因素有许多: 功能 缺少的功能 功能的组合 设计 人 时间4、案例学习:两段程序我们来近距离回顾两段程序。第一个是你见过的第一个Go程序,是属于你的历史时刻。第二个是我们见过的第一个Go程序,是属于全世界所有Gophers的历史时刻。先看第一个“hello, world”5、hello.b1. main()2. extrna,b,c;3. putchar(a);putchar(b);putchar(c);putchar(!*n);4. 5.

4、ahell;6. bo,w;7. corld;上面这段代码首先出现在1972年Brian W. Kernighan的B语言教程中(也有另外一说是出现在那之前的BCPL语言中)。6、hello.c1. main()2. 3. printf(hello,world);4. 上面这段代码出现在1974年Brian W. Kernighan编写的Programming in C: A Tutorial中。这份教程当时是作为Unix v5文档的一部分。7、hello.c1. main()2. 3. printf(hello,worldn);/译注:与上面的hello.c相比,多了个换行符n输出4. 这段

5、代码首次出现在1978年Brian W. Kernighan和Dennis M. Ritchie合著的The C Programming Language一书中。8、hello.c, 标准C草案1. #include/译注:与上面hello.c相比,多了这个头文件包含2. 3. main()4. 5. printf(hello,worldn);6. 这段代码出现在1988年Brian W. Kernighan和Dennis M. Ritchie合著的The C Programming Language第二版一书中,基于标准C草案。9、hello.c,标准C891. #include2. 3.

6、main(void)/译注:与上面hello.c相比,多了个void4. 5. printf(hello,worldn);6. 这段代码出现在1988年Brian W. Kernighan和Dennis M. Ritchie合著的The C Programming Language第二版第二次修订中。10、一两代之后(省略所有中间语言)关于Golang的讨论开始于2007年年末。第一版语言规范起草于2008年3月份。用于实验和原型目的的编译器开发工作已经展开。最初的编译器输出的是C代码。语言规范一形成,我们就重写了编译器,输出本地代码(机器码)。11、hello.go, 2008年6月6日1.

7、 packagemain2. 3. funcmain()int4. printhello,worldn;5. return0;6. 12、hello.go,2008年6月27日1. packagemain2. 3. funcmain()4. printhello,worldn;5. 当main函数返回,程序调用exit(0)。13、hello.go,2008年8月11日1. packagemain2. 3. funcmain()4. print(hello,worldn);5. print调用加上了括号,这时print是一个函数,不再是一个原语。14、hello.go,2008年10月24日1

8、. packagemain2. 3. importfmt4. 5. funcmain()6. fmt.printf(hello,worldn);7. 我们熟知并喜欢的printf来了。15、hello.go,2009年1月15日1. packagemain2. 3. importfmt4. 5. funcmain()6. fmt.Printf(hello,worldn);7. 头母大写的函数名用作才是导出的符号。16、hello.go, 2009年12约11日1. packagemain2. 3. importfmt4. 5. funcmain()6. fmt.Printf(hello,wor

9、ldn)7. 不再需要分号。这是在2009年11月10日Golang开发发布后的一次重要改变。这也是当前版本的hello, world我们花了些时间到达这里(32年!)都是历史了!17、不仅仅有C我们从”C”开始,但Go与C相比有着巨大的不同。其他一些语言影响和贯穿于Go的设计当中。C: 语句和表达式语法Pascal: 声明语法Modula 2, Oberon 2:包CSP, Occam, Newsqueak, Limbo, Alef: 并发BCPL: 分号规则Smalltalk: 方法(method)Newsqueak: -, :=APL: iota等等。也有一些是全新发明的,例如defer

10、、常量。还有一些来自其他语言的优点和缺点:C+, C#, Java, JavaScript, LISP, Python, Scala, 18、hello.go,Go 1版将我们带到了今天。1. packagemain2. 3. importfmt4. 5. funcmain()6. fmt.Println(Hello,Gophers(someofwhomknow中文)!)7. 我们来深入挖掘一下,把这段代码做一个拆解。19、Hello, World的16个tokens1. package2. main3. import4. fmt5. func6. main7. (8. )9. 10. fmt

11、11. .12. Println13. (14. Hello,Gophers(someofwhomknow中文)!15. )16. 20、package早期设计讨论的主要话题:扩展性的关键package是什么?来自Modula-2等语言的idea为什么是package? 拥有编译构建所需的全部信息 没有循环依赖(import) 没有子包 包名与包路径分离 包级别可见性,而不是类型级别 在包内部,你拥有整个语言,在包外部,你只拥有包许可的东西。21、main一个C语言遗留风范尽显之处最初是Main,原因记不得了。主要的包,main函数很特别,因为它是初始化树(initialization tre

12、e)的根(root)。22、import一种加载包的机制通过编译器实现(有别于文本预处理器。译注:C语言的include是通过preprocessor实现的)努力使其高效且线性导入的一个包,而不是一个标识符(identifiers)集合(译注:C语言的include是将头文件里的标识符集合引入)至于export,它曾经是一个关键字。23、”fmt”包路径(package path)只是一个字符串,并非标识符的列表。让语言避免定义它的含义 适应性。(Allows the language to avoid defining what it meansadaptability)从一开始就想要一个U

13、RL作为一个选项。(译注:类似import “/go/tools/xxx)可以应付将来的发展。24、func一个关键字,用于引入函数(类型、变量、常量),易于编译器解析。对于函数字面量(闭包)而言,易于解析非常重要。顺便说一下,最初这个关键字不是func,而是function。小插曲:Mail thread from February 6, 2008From: Ken ThompsonTo: gri, rlarry and sergey came by tonight. we talked about go for more than an hour. they both

14、said they liked it very much.p.s. one of larrys comments was “why isnt function spelled func?”From: Rob PikeTo: ken, grifine with me. seems compatible with var.anyway we can always say, “larry said to call it func”25、main程序执行的起点。除非它不是。(译注:main不是起点,rob大神的意思是不是指下列情形,比如go test测试包,在google app engine上的go

15、程序不需要main)将初始化与正常执行分离,早期计划之中的。初始化在哪里发生的?(译注:说的是package内的func init() .函数吧)回到包设计。(译注:重温golang的package设计思想)26、()看看,没有voidmain没有返回值,由运行时来处理main的返回后的事情。没有函数参数(命令行选项通过os包获取)没有返回值返回值以及语法27、用的是大括号,而不是空格(译注:估计是与python的空格缩进对比)同样也不是方括号。为什么在括号后放置换行符(newline)?28、fmt所有导入的标识符均限定于其导入的包。(All imported identifiers are

16、 qualified by their import.)每个标识符要么是包或函数的本地变量,要么被类型或导入包限定。对代码可读性的重大影响。为什么是fmt,而不是format?29、.句号token在Go中有多少使用?(很多)a.B的含义需要使用到类型系统但这对于人类来说非常清晰,读起来也非常容易。针对指针的自动转换(没有-)。30、PrintlnPrintln,不是println,头母大写才是导出符号。知道它是反射驱动的(reflection-driven)可变参数函数参数类型是(); 2010年2月1日变成(interface)31、(传统函数语法32、”Hello, Gophers (s

17、ome of whom know 中文)!”UTF-8编码的源码输入。字符串字面量也自动是utf8编码格式的。但什么是字符串(string)呢?首批写入规范的语法规则,今天很难改变了。(/strings)33、)没有分号在go发布后不久我们就去除了分号早期曾胡闹地尝试将它们(译注:指得是括号)去掉最终接受了BCPL的方案34、第一轮结束。旁白:还没有讨论到的 类型 常量 方法 interface 库 内存管理 并发(接下来将讨论)外加工具,生态系统,社区等。语言是核心,但也只是我们故事的一部分。35、成功要素: 站在巨人的肩膀上(building on histo

18、ry) 经验之作(building on experience) 译注:最初的三个神级语言设计者 设计过程 早期idea提炼到最终的方案中 由一个小团队专门集中精力做最终:承诺Go 1.0锁定了语言核心与标准库。36、另一轮让我们看第二个程序的类似演化过程。37、问题:素数筛(Prime sieve)问题来自于Communicating Sequential Processes, by C. A. R. Hoare, 1978。“问题:以升序打印所有小于10000的素数。使用一个process数组:SIEVE,其中每个process从其前驱元素输入一个素数并打印 它。接下 来这个process

19、从其前驱元素接收到一个升序数字流并将它们传给其后继元素,这个过程会剔除掉所有是最初素数整数倍的数字。38、解决方案在1978年的CSP论文中。(注意不是Eratosthenes筛)这个优美的方案是由David Gries贡献出来的。39、CSP在Hoare的CSP论文中:1. SIEVE(i:1.100):2. p,mp:integer;3. SIEVE(i-1)?p;4. print!p;5. mp:=p;commentmpisamultipleofp;6. *m:integer;SIEVE(i-1)?m7. *mmpmp:=mp+p;8. m=mpskip9. |mmpSIEVE(i+1)

20、!m10. 11. |SIEVE(0):print!2;n:integer;n:=3;12. *n10000SIEVE(1)!n;n:=n+213. |SIEVE(101):*n:integer;SIEVE(100)?nprint!n14. |print:*(i:0.101)n:integer;SIEVE(i)?n.15. 没有channel。能处理的素数的个数是在程序中指定的。40、Newsqueakcirca 1988。Rob Pike语言设计,Tom Cargill和Doug McIlroy实现。使用了channels,这样个数是可编程的。(channel这个idea从何而来?)1. c

21、ounter:=prog(end:int,c:chanofint)2. 3. i:int;4. for(i=2;iend;i+)5. c-=i;6. ;7. 8. filter:=prog(prime:int,listen:chanofint,send:chanofint)9. 10. i:int;11. for(;)12. if(i=-listen)%prime)13. send-=i;14. ;15. 16. sieve:=prog(c:chanofint)17. 18. for(;)19. prime:=用于发送;int)5. fori:=2;i+6. ch=i;/Senditochan

22、nelch.7. 8. 9. 10. /Copythevaluesfromchannelintochannelout,11. /removingthosedivisiblebyprime.12. funcFilter(in*chanint,primeint)13. for;14. i:=out=i;/Senditochannelout.17. 18. 19. 20. 21. /Theprimesieve:Daisy-chainFilterprocessestogether.22. funcSieve()23. ch:=new(chanint);/Createanewchannel.24. go

23、Generate(ch);/StartGenerate()asasubprocess.25. for;26. prime:=ch;27. printf(%dn,prime);28. ch1:=new(chanint);29. goFilter(ch,ch1,prime);30. ch=ch1;31. 32. 33. 34. funcMain()35. Sieve();36. 42. sieve.go,2008年7月22日-用于发送;-用于接收。Channel仍然是指针。但现在main不是大写字母开头的了。1. packagemain2. 3. /Sendthesequence2,3,4,toc

24、hannelch.4. funcGenerate(ch*chan-int)5. fori:=2;i+6. ch-i/Senditochannelch.7. 8. 9. 10. /Copythevaluesfromchannelintochannelout,11. /removingthosedivisiblebyprime.12. funcFilter(in*chan-int,out*chan-int,primeint)13. for14. i:=-in;/Receivevalueofnewvariableifromin.15. ifi%prime!=016. out-i/Senditocha

25、nnelout.17. 18. 19. 20. 21. /Theprimesieve:Daisy-chainFilterprocessestogether.22. funcSieve()23. ch:=new(chanint);/Createanewchannel.24. goGenerate(ch);/StartGenerate()asasubprocess.25. for26. prime:=-ch;27. printf(%dn,prime);28. ch1:=new(chanint);29. goFilter(ch,ch1,prime);30. ch=ch131. 32. 33. 34.

26、 funcmain()35. Sieve()36. 43、sieve.go,2008年9月17日通信操作符现在是-。channel仍然是指针。1. packagemain2. 3. /Sendthesequence2,3,4,tochannelch.4. funcGenerate(ch*chan-int)5. fori:=2;i+6. ch-i/Senditochannelch.7. 8. 9. 10. /Copythevaluesfromchannelintochannelout,11. /removingthosedivisiblebyprime.12. funcFilter(in*cha

27、n-int,out*-chanint,primeint)13. for14. i:=-in;/Receivevalueofnewvariableifromin.15. ifi%prime!=016. out-i/Senditochannelout.17. 18. 19. 20. 21. /Theprimesieve:Daisy-chainFilterprocessestogether.22. funcSieve()23. ch:=new(chanint);/Createanewchannel.24. goGenerate(ch);/StartGenerate()asasubprocess.25

28、. for26. prime:=-ch;27. print(prime,n);28. ch1:=new(chanint);29. goFilter(ch,ch1,prime);30. ch=ch131. 32. 33. 34. funcmain()35. Sieve()36. 44、sieve.go,2009年1月6日引入了make内置操作符。没有指针。编码错误!(有个*被留下了,错误的参数类型)1. packagemain2. 3. /Sendthesequence2,3,4,tochannelch.4. funcGenerate(chchan-int)5. fori:=2;i+6. ch-

29、i/Senditochannelch.7. 8. 9. 10. /Copythevaluesfromchannelintochannelout,11. /removingthosedivisiblebyprime.12. funcFilter(inchan-int,out*-chanint,primeint)13. for14. i:=-in;/Receivevalueofnewvariableifromin.15. ifi%prime!=016. out-i/Senditochannelout.17. 18. 19. 20. 21. /Theprimesieve:Daisy-chainFil

30、terprocessestogether.22. funcSieve()23. ch:=make(chanint);/Createanewchannel.24. goGenerate(ch);/StartGenerate()asasubprocess.25. for26. prime:=-ch;27. print(prime,n);28. ch1:=make(chanint);29. goFilter(ch,ch1,prime);30. ch=ch131. 32. 33. 34. funcmain()35. Sieve()36. 45、sieve.go,2009年9月25日第一个正确的现代版本

31、。同样,大写头母不见了,使用了fmt。1. packagemain2. 3. importfmt4. 5. /Sendthesequence2,3,4,tochannelch.6. funcgenerate(chchan-int)7. fori:=2;i+8. ch-i;/Senditochannelch.9. 10. 11. 12. /Copythevaluesfromchannelintochannelout,13. /removingthosedivisiblebyprime.14. funcfilter(src-chanint,dstchan-int,primeint)15. fori

32、:=rangesrc/Loopovervaluesreceivedfromsrc.16. ifi%prime!=017. dst-i;/Senditochanneldst.18. 19. 20. 21. 22. /Theprimesieve:Daisy-chainfilterprocessestogether.23. funcsieve()24. ch:=make(chanint);/Createanewchannel.25. gogenerate(ch);/Startgenerate()asasubprocess.26. for27. prime:=-ch;28. fmt.Print(prime,n);29. ch1:=make(chanint);30. gofilter(ch,ch1,prime);31. ch=ch1;32. 33. 34. 35. funcmain()36. sieve();37. 46、sieve.go,2009年12月10日分号不见了。程序已经与现在一致了。1. packagemain2. 3. importfmt4. 5. /Sendthesequence2,3,4,tochannelch.6. funcgenerate(chchan-int)7. fori:=2;i+8. ch-i/Senditochannelch.9. 10. 11. 12. /

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论