#《Go 语音圣经(中文版)》

#程序结构

#指针

任何类型的指针的零值都是nil

如果p指向某个有效变量,那么p != nil测试为真。

指针之间也是可以进行相等测试的,只有当它们指向同一个变量或全部是nil时才相等。

另一个创建变量的方法是调用用内建的new函数。表达式new(T)将创建一个T类型的匿名变量,初始化为T类型的零值,然后返回变量地址,返回的指针类型为*T

对于在包一级声明的变量来说,它们的生命周期和整个程序的运行周期是一致的。

局部变量的声明周期则是动态的:每次从创建一个新变量的声明语句开始,直到该变量不再被引用为止,然后变量的存储空间可能被回收。

函数的右小括弧也可以另起一行缩进,同时为了防止编译器在行尾自动插入分号而导致的编译错误,可以在末尾的参数变量后面显式插入逗号。

1
2
3
4
5
6
for t := 0.0; t < cycles*2*math.Pi; t += res {
x := math.Sin(t)
y := math.Sin(t*freq + phase)
img.SetColorIndex(size+int(x*size+0.5), size+int(y*size+0.5),
blackIndex)
}
1
2
3
4
5
6
7
8
for t := 0.0; t < cycles*2*math.Pi; t += res {
x := math.Sin(t)
y := math.Sin(t*freq + phase)
img.SetColorIndex(
size+int(x*size+0.5), size+int(y*size+0.5),
blackIndex, // 最后插入的逗号不会导致编译错误,这是Go编译器的一个特性
) // 小括弧另起一行缩进,和大括弧的风格保存一致
}

编译器会自动选择在栈上还是在堆上分配局部变量的存储空间。

#赋值

自增和自减是语句,而不是表达式,因此x = i++之类的表达式是错误的。

#类型

一个类型声明语句创建了一个新的类型名称,和现有类型具有相同的底层结构。新命名的类型提供了一个方法,用来分隔不同概念的类型,这样即使它们底层类型相同也是不兼容的。

1
2
type 类型名字 底层类型
type Celsius float64

类型声明语句一般出现在包一级,因此如果新创建的类型名字的首字符大写,则在外部包也可以使用。

对于每一个类型T,都有一个对应的类型转换操作T(x),用于将x转为T类型,如果T是指针类型,可能会需要用小括弧包装T,比如(*int)(0)

在任何情况下,运行时不会发生转换失败的错误,错误只会发生在编译阶段。

底层数据类型决定了内部结构和表达方式,也决定是否可以像底层类型一样对内置运算符的支持。