之后我们在邮件上交流,这里是内容摘选:
Robert:以C语言为原型,修补部分明显的缺陷,去掉垃圾功能,添加一些缺失的功能。
Rob:命名为“Go”,好处有很多,这名字非常简短,容易拼写。工具可以叫做:goc、gol、goa。如果有可交互的调试器/解释器也可以简单地叫它“Go”,后缀名用 .go。
Robert:定义空接口语法:interface{}。所有接口都通过这个实现,因此可以用它代替void*。
我们没有一开始就设计出所有的功能,之后花了一年的时间才确定了array和slice功能,不过也有很多语言的特色在最初几天就已经确定下来的。
注意:Robert说要以C语言为原型,而不是C++!但实际上我们也并不是真的从C开始,只是从中借了部分内容,比如运算符、括号和几个相同的关键字。当然为了让它成为最适合我们的语言,我们从所有了解的语言里都借取了一些特性。
最后结果毫无疑问跟C或C++大不相同。以下是Go从C和C++简化的功能:
规范的语法(不需要符号表来解析)
垃圾回收(独有)
无头文件
明确的依赖
无循环依赖
常量只能是数字
int和int32是两种类型
字母大小写设置可见性(letter case sets visibility)
任何类型(type)都有方法(不是类型)
没有子类型继承(不是子类)
包级别初始化以及明确的初始化顺序
文件被编译到一个包里
包package-level globals presented in any order
没有数值类型转换(常量起辅助作用)
接口隐式实现(没有“implement”声明)
嵌入(不会提升到超类)
方法按照函数声明(没有特别的位置要求)
方法即函数
接口只有方法(没有数据)
方法通过名字匹配(而非类型)
没有构造函数和析构函数
postincrement(如++i)是状态,不是表达式
没有preincrement(i++)和predecrement
赋值不是表达式
明确赋值和函数调用中的计算顺序(没有“sequence point”)
没有指针运算
内存一直以零值初始化
局部变量取值合法
方法中没有“this”
分段的堆栈
没有静态和其它类型的注释
没有模板
没有异常
内建string、slice和map
数组边界检查
因为有这么多功能的简化,我相信Go比C和C++更有表现力。Less can be more!
但是也不能全部丢弃。你需要把想法分为模块,例如:类型如何工作、能够实际上良好运行的语法以及有助于保证类库交互的东西。
我们也加入了一下C和C++里没有的东西,比如slice和map、复合文本(composite literal)、顶层文件表达式(这是一个大问题,但经常被忽视)、映射(reflection)、垃圾回收等等,我们还非常自然地加入了并发性。
很明显还缺少了类型层次结构,这让我很生气。
在Go语言的首次启航中,我得到了一个“我不能在没有泛型的环境下工作”的反馈,这真是一个奇怪的言论。
平心而论,我觉得他可能是因为在C++里用惯了STL的原因。从字面意思来看,这就是说着写一个int list或者string map对他来说是一个非常大的负担。我不会在这种奇怪的问题上花太长的时间,所以这种需要泛型支持的也一样。
但更重要的是,只有类型是用来解决这样的问题的,既不是多态函数(polymorphic function)也不是语言原语(language primitive)或者其它类型的帮助,只有类型!
这就是卡住我的的细节。
从C++和Java转向Go的程序员很怀念使用类型编程的方式,特别是继承和子类这样的概念。也许关于“类型”我只是一个门外汉,但我真没发现模板有什么好处。
我已故的朋友Alain Fournier曾告诉我,他认为学术工作最基本的要求就是分工。你知道吗?类型层次也只是一种分类法。你需要决定什么东西封装在什么里面,每个对象的父类型是什么?到底是A继承B还是B继承A?可排序数组究竟是用来排序的数组还是一个通过数组实现的排序器?如果你坚信类型决定设计那这个就是必须理清的问题!
Robert:以C语言为原型,修补部分明显的缺陷,去掉垃圾功能,添加一些缺失的功能。
Rob:命名为“Go”,好处有很多,这名字非常简短,容易拼写。工具可以叫做:goc、gol、goa。如果有可交互的调试器/解释器也可以简单地叫它“Go”,后缀名用 .go。
Robert:定义空接口语法:interface{}。所有接口都通过这个实现,因此可以用它代替void*。
我们没有一开始就设计出所有的功能,之后花了一年的时间才确定了array和slice功能,不过也有很多语言的特色在最初几天就已经确定下来的。
注意:Robert说要以C语言为原型,而不是C++!但实际上我们也并不是真的从C开始,只是从中借了部分内容,比如运算符、括号和几个相同的关键字。当然为了让它成为最适合我们的语言,我们从所有了解的语言里都借取了一些特性。
最后结果毫无疑问跟C或C++大不相同。以下是Go从C和C++简化的功能:
规范的语法(不需要符号表来解析)
垃圾回收(独有)
无头文件
明确的依赖
无循环依赖
常量只能是数字
int和int32是两种类型
字母大小写设置可见性(letter case sets visibility)
任何类型(type)都有方法(不是类型)
没有子类型继承(不是子类)
包级别初始化以及明确的初始化顺序
文件被编译到一个包里
包package-level globals presented in any order
没有数值类型转换(常量起辅助作用)
接口隐式实现(没有“implement”声明)
嵌入(不会提升到超类)
方法按照函数声明(没有特别的位置要求)
方法即函数
接口只有方法(没有数据)
方法通过名字匹配(而非类型)
没有构造函数和析构函数
postincrement(如++i)是状态,不是表达式
没有preincrement(i++)和predecrement
赋值不是表达式
明确赋值和函数调用中的计算顺序(没有“sequence point”)
没有指针运算
内存一直以零值初始化
局部变量取值合法
方法中没有“this”
分段的堆栈
没有静态和其它类型的注释
没有模板
没有异常
内建string、slice和map
数组边界检查
因为有这么多功能的简化,我相信Go比C和C++更有表现力。Less can be more!
但是也不能全部丢弃。你需要把想法分为模块,例如:类型如何工作、能够实际上良好运行的语法以及有助于保证类库交互的东西。
我们也加入了一下C和C++里没有的东西,比如slice和map、复合文本(composite literal)、顶层文件表达式(这是一个大问题,但经常被忽视)、映射(reflection)、垃圾回收等等,我们还非常自然地加入了并发性。
很明显还缺少了类型层次结构,这让我很生气。
在Go语言的首次启航中,我得到了一个“我不能在没有泛型的环境下工作”的反馈,这真是一个奇怪的言论。
平心而论,我觉得他可能是因为在C++里用惯了STL的原因。从字面意思来看,这就是说着写一个int list或者string map对他来说是一个非常大的负担。我不会在这种奇怪的问题上花太长的时间,所以这种需要泛型支持的也一样。
但更重要的是,只有类型是用来解决这样的问题的,既不是多态函数(polymorphic function)也不是语言原语(language primitive)或者其它类型的帮助,只有类型!
这就是卡住我的的细节。
从C++和Java转向Go的程序员很怀念使用类型编程的方式,特别是继承和子类这样的概念。也许关于“类型”我只是一个门外汉,但我真没发现模板有什么好处。
我已故的朋友Alain Fournier曾告诉我,他认为学术工作最基本的要求就是分工。你知道吗?类型层次也只是一种分类法。你需要决定什么东西封装在什么里面,每个对象的父类型是什么?到底是A继承B还是B继承A?可排序数组究竟是用来排序的数组还是一个通过数组实现的排序器?如果你坚信类型决定设计那这个就是必须理清的问题!