1.块
块为一对大括号括住的声明和语句。块 = "{" { 语句 ";" } "}" .
除显式源码块外,还有隐式块:
-
- 全域块 包含所有的Go源码文本。
- 每个包都有包含其所有Go源码文本的 包块。
- 每个文件都有包含其所有Go源码文本的 文件块。
- 每个
if
、for
和switch
语句都被视为处于其自身的隐式块中。
- 每个
switch
或 select
语句中的子句其行为如同隐式块。
块可嵌套并会影响作用域。
2.标识符
标识符被用来命名程序实体,例如变量和类型。一个标识符由一个或多个字母和数字组成。 标识符的第一个字符必须是字母。
给定一个标识符集,若其中一个标识符不同于该集中的任一标识符,那么它就是唯一的。 若两个标识符拼写不同,或它们出现在不同的包中且未 导出,那么它们就是不同的。否则,它们就是相同的。
空白标识符
空白标识符 通过下划线字符 _ 表示, 它可像其它标识符一样用于声明,但该标识符不能传入一个新的绑定。
预声明标识符
在全局块中,以下标识符是隐式声明的:
类型:
bool byte complex64 complex128 error float32 float64
int int8 int16 int32 int64 rune string
uint uint8 uint16 uint32 uint64 uintptr
常量:
true false iota
零值:
nil
函数:
append cap close complex copy delete imag len
make new panic print println real recover
已导出标识符
标识符可被 导出 以允许从另一个包访问。同时符合以下条件即为已导出标识符:
-
- 标识符名的第一个字符为Unicode大写字母(Unicode类别“Lu”);且
- 该标识符在包块中已声明或为字段名或 方法名。
其它所有标识符均为未导出的。
关键字
以下为保留关键字,不能用作标识符。
break default func interface select
case defer go map struct
chan else goto package switch
const fallthrough if range type
continue for import return var
3.声明和作用域
声明可将非空白标识符"_"绑定到一个常量、类型、变量、函数或包。 在程序中,每个标识符都必须被声明。
作用域 即为已声明标识符所表示的常量、类型、变量、函数或包在源代码中的作用范围。
作用域说明:
- 预声明标识符的作用域为全域块。
- 在顶级(即在任何函数之外)声明的表示常量、类型、变量或函数(而非方法)的标识符其作用域为该包块。
- 已导入包的包名作用域为包含该导入声明的文件块。
- 表示方法接收器、函数形参或返回值变量的标识符,其作用域为该函数体。
- 在函数中声明为常量或变量的标识符,其作用域始于该函数中具体常量实现或变量实现ShortVarDecl表示短变量声明)的结尾,止于最内部包含块的结尾。
- 在函数中声明为类型的标识符,其作用域始于该函数中具体类型实现的标识符,止于最内部包含块的结尾。
注意:
- 同一标识符不能在同一块中声明两次,且在文件与包块中不能同时声明。
- 在块中声明的标识符可在其内部块中重新声明。 当其内部声明的标识符在作用域中时,即表示其实体在该内部声明中声明。
- 包子句(package xxx)并非声明;包名不会出现在任何作用域中。 其目的是为了识别该文件是否属于相同的包并为导入声明指定默认包名。
标签作用域:
标签通过标签语句声明(标识符:语句),并用于 break、continue 和 goto 语句.例如:
L:
for i < n {
switch i {
case 5:
break L
}
}
定义不会使用的标签是非法的。与其它标识符相反,标签并不限定作用域且与非标签标识符并不冲突。 标签的作用域为除任何嵌套函数体外其声明的函数体。
4.各种声明
常量声明
const Pi float64 = 3.14159265358979323846
const zero = 0.0 // 无类型化浮点常量
const (
size int64 = 1024
eof = -1 // 无类型化整数常量
)
const a, b, c = 3, 4, "foo" // a = 3, b = 4, c = "foo", 无类型化整数和字符串常量
const u, v float32 = 0, 3 // u = 0.0, v = 3.0
iota
iota可以被认为是一个可被编译器修改的常量,在每一个const关键字出现时被重置为0,然后在下一个const出现之前,每出现一次iota,其所代表的数字会自动增1
const ( // iota重置为0
c0 = iota // c0 == 0
c1 = iota // c1 == 1
c2 = iota // c2 == 2
)
const (
Sunday = iota
Monday
Tuesday
Wednesday
Thursday
Friday
Partyday
numberOfDays // 该常量未导出
)
在表达式列表中,每个 iota 的值都相同,因为它只在每个常量实现后增量。
const (
bit0, mask0 = 1 << iota, 1<<iota - 1 // bit0 == 1, mask0 == 0
bit1, mask1 // bit1 == 2, mask1 == 1
_, _ // skips iota == 2
bit3, mask3 // bit3 == 8, mask3 == 7
)
类型声明
声明类型不继承任何方法绑定到现存类型, 但接口类型或复合类型元素的方法集保持不变:
// Mutex为带有Lock和Unlock两个方法的数据类型.
type Mutex struct { /* Mutex字段 */ }
func (m *Mutex) Lock() { /* Lock实现*/ }
func (m *Mutex) Unlock() { /* Unlock实现*/ }
// NewMutex和Mutex拥有相同的组成,但它的方法集为空.
type NewMutex Mutex
// PtrMutex的基础类型的方法集保持不变.
// 但PtrMutex的方法集为空.
type PtrMutex *Mutex
// *PrintableMutex的方法集包含方法
// Lock和Unlock绑定至其匿名字段Mutex.
type PrintableMutex struct {
Mutex
}
// MyBlock为与Block拥有相同方法集的接口类型.
type MyBlock Block
类型声明可用来定义不同的布尔值、数字或字符串类型并对其附上方法:
type TimeZone int
const (
EST TimeZone