《Tony Bai · Go语言第一课》 总结
简单
内置垃圾收集
首字母大小写决定可见性,无需通过额外关键字修饰;
变量初始为类型零值,避免以随机值作为初值的问题;
内置数组边界检查,极大减少越界访问带来的安全隐患;
内置并发支持,简化并发程序设计;
内置接口类型,为组合的设计哲学奠定基础;
原生提供完善的工具链,开箱即用;
显示
func main()
{
var a int16=5
var b int = 8
var c int64
c=a+b
fmt.Printf("%d\n", c)
}
如果我们编译这段程序,将得到类似这样的编译器错误:“invalid operation: a + b
(mismatched types int16 and int)”。我们能看到 Go 与 C 语言的隐式自动类型转换不
同,Go 不允许不同类型的整型变量进行混合计算,它同样也不会对其进行隐式的自动转
换。
因此,如果要使这段代码通过编译,我们就需要对变量 a 和 b 进行显式转型,就像下面代
码段中这样:
c = int64(a) + int64(b)
fmt.Printf("%d\n", c)
组合
go各类型之间相互独立,没有子类型
每个类型都可以有自己的方法集合
实现某个接口时,无需像java一样采用特定的关键字修饰
包之间相互独立,没有子包的概念
类型嵌入
通过类型的嵌入,可以将已经实现的功能嵌入到新的类型中
垂直嵌入
被嵌入的类型和新类型两者之间没有任何关系,甚至相互完全不知道对方的存在,更没有
经典面向对象语言中的那种父类、子类的关系,以及向上、向下转型(Type Casting)。
type poolLocal struct {
private interface{}
shared []interface{}
Mutex
pad [128]byte
}
poolLocal 这个结构体类型中嵌入了类型 Mutex,这就使得
poolLocal 这个类型具有了互斥同步的能力,我们可以通过 poolLocal 类型的变量,直接
调用 Mutex 类型的方法 Lock 或 Unlock。
水平嵌入
通过接受 接口类型参数 的普通函数进行组合
func ReadAll(r io.Reader)([]byte, error)
函数 ReadAll 通过 io.Reader 这个接口,将 io.Reader 的实现与 ReadAll 所在
的包低耦合地水平组合在一起了,从而达到从任意实现 io.Reader 的数据源读取所有数据
的目的。
并发
将面向多核、原生支持并发作为了新语言的设计原则之一
Go 放弃了传统的基于操作系统线程的并发模型,而采用了用户层轻量级线程,Go 将之称为 goroutine。
goroutine 占用的资源非常小,Go 运行时默认为每个 goroutine 分配的栈空间仅 2KB。
提供了开销较低的 goroutine 的同时,Go 还在语言层面内置了辅助并发设计的原语:
channel 和 select。开发者可以通过语言内置的 channel 传递消息或实现同步,并通过
select 实现多路 channel 的并发控制。
goroutines 各自执行特定的工作,通过 channel+select 将 goroutines 组合连接起来。
面向工程
去除包的循环依赖,
包路径是唯一的,而包名不必唯一的。导入路径必须唯一标识要导入的包,而名称只是
包的使用者如何引用其内容的约定。
故意不支持默认函数参数
增加类型别名(type alias),支持大规模代码库的重构。
gofmt,它统一了 Go 语言的代码风格