Google Go 初识
原文: Google Go:初级读本 http://www.infoq.com/cn/articles/google-go-primer
几个印象深刻的特性:
* 综述
Go语言的设计者计划设计一门简单、高效、安全和 并发的语言。这门语言简单到甚至不需要有一个符号表来进行词法分析。它可以快速地编译;整个工程的编译时间在秒以下的情况是常事。它具备垃圾回收功能,因 此从内存的角度是安全的。它进行静态类型检查,并且不允许强制类型转换,因而对于类型而言是安全的。同时语言还内建了强大的并发实现机制。
Go语言的作者在设计这一语言时坚持一个单一的指导原则:简单明了至上。一些新的语法构件提供了简明地表达一些约定俗成的概 念的方式,相较之下用C表达显得冗长。而其他方面则是针对几十年的使用所呈现出来的一些不合理的语言选择作出了改进。
* 支持多返回值。我想说:这真的会很实用!
多返回值
在C语言当中常见的做法是保留一个返回值来表示错误(比如,read()返回 0),或 者保留返回值来通知状态,并将传递存储结果的内存地址的指针。这容易产生了不安全的编程实践,因此在像Go语言这样有良好管理的语言中是不可行的。
认识到这一问题的影响已超出了函数结果与错误通讯的简单需求的范畴,Go的作者们在语言中内建了函数返回多个值的能力。
作为例子,这个函数将返回整数除法的两个部分:
func divide(a, b int) (int, int) {
quotient := a / b
remainder := a % b
return quotient, remainder
}有了多个返回值,有良好的代码文档会更好——而Go允许你给返回值命名,就像参数一样。你可以对这些返回的变量赋值,就像其它的变量一样。所以我们 可以重写divide:
func divide(a, b int) (quotient, remainder int) {
quotient = a / b
remainder = a % b
return
}多返回值的出现促进了"comma-ok"的模式。有可能失败的函数可以返回第二个布尔结果来表示成功。作为替代,也可以返回一个错误对象,因此像 下面这样的代码也就不见怪了:
if result, ok := moreMagic(); ok {
/* Do something with result */
}
* 数据类型:Slice,Map,以支持更加灵活的数据处理,和python差不多。
* 类型不支持继承,推荐使用组合和委托(代理)。支持接口,但是不用显示声明,编译器会根据方法签名自动识别。
因为 不是继承,所以面向对象的“重载”就不存在了,这就意味着,你无法在子类覆盖父类的实现。
这种组合是通过委派来实现的,而不是继承。一旦匿名成员的方法被调用,控制流整个都被委派给了该方法。所以你无法做到和下面的例子一 样来模拟类型层次:
type Base struct {}
func (Base) Magic() { fmt.Print("base magic") }
func (self Base) MoreMagic() {
self.Magic()
self.Magic()
}
type Foo struct {
Base
}
func (Foo) Magic() { fmt.Print("foo magic") }当你创建一个Foo对象时,它将会影响Base的两个方法。然而,当你调用MoreMagic时, 你将得不到期望的结果:
f := new(Foo)
f.Magic() //=> foo magic
f.MoreMagic() //=> base magic base magic
* 支持并发,提供了两个机制:Gorountines和Channel。简单来看,GoRountines不需要返回值(fire & forget),Channel支持异步调用。
* 文章最后提到,不支持异常和泛型,这是个缺失,然而对于Go的底层语言的目的(求快!),这一点似乎有情可原。异常就没办法了,泛型,通过匿名函数和接口来解决?