GO语言规范-声明及作用域

块是指在相匹配的花括号内的,可能为空的一系列声明和语句。
在源代码中除了显式的块,还有隐式的块:

  • 全局块:涵盖了所有Go源码文本
  • 包块:涵盖了一个包的所有Go源码文本
  • 文件块:涵盖了在一个文件内所有Go源码文本
  • 每个for、if、switch语句都视为它自身的隐式块
  • switch、select语句的每个条件都是一个隐式块
    块可以嵌套并影响作用域。

声明及作用域

声明就是绑定一个非空标识 符到常量、类型、变量、函数、标签或包。程序中的每个标识符都必须先声明。标识符不能在同一个块中两次声明,标识符不能在文件块和包块中同时声明。
空标识符(“_”)可以像其他的标识符一样在声明中使用,但它不是一个绑定,所以也不是被声明的。在包块中,标识符init只能用于init函数的声明,与空标识符一样也不是一个绑定。

标识符的作用域是一个被声明的标识符所表示的常量、类型、变量、函数、标签或包在源码文本中的延伸。

Go使用块作为词法作用域分析:

  1. 预定义标识符的作用域是全局块
  2. 在顶层(所有函数之外)声明的标识符所表示的常量、类型、变量、函数(除了方法)的作用域是包块
  3. 在含有import声明的文件里,被导入的包的包名的作用域是文件块
  4. 表示方法接收者、函数参数或结果变量的标识符,其作用域是函数体
  5. 函数中声明的常量或变量标识符的作用域开始于它声明之时,结束于包含它的最内层的块的末尾。
  6. 函数中声明的类型标识符的作用域开始于它声明之时,结束于包含它的最内层的块的末尾。

在块中已经声明的标识符,在内层块中可以被重新声明一个标识符,内层声明的标识符的作用域只在内层块的范围内。
package子句并不是一个声明,其包名也不会出现在任何作用域。其目的是标识文件属于同一个包,并指定了在import声明中的默认包名。

标签作用域

标签由标签语句声明,用于break、continue、goto语句。定义一个标签却不使用是错误的。与其他的标识符不同,标签不是块作用域的,不要让非标签标识符与标签有冲突。标签的作用域是函数体,但不包括嵌套的函数的函数体。

导出标识符

导出标识符允许其他的包访问它。满足以下条件的标识符就是导出的

  1. 标识符名称的第一个字母是大写字母(Unicode中的“Lu”类),并且
  2. 标识符是在包块中声明的,或者是一个字段名或方法名。

标识符的唯一性

两个标识符如果拼写不同,那就是不同的;如果它们在不同的包里并且没有导出它们也是不同的。

类型声明

类型声明就是将一个称为类型名的标识符绑定到一个类型上。类型声明有两种形式:别名和类型定义

别名

将一个标识符绑定到一个类型上

type(
  nodeList = []*Node	// nodList与[]*Node是同一个类型
  Polar = ploar      // Polar与polar代表的是同一个类型
)

类型定义

在基础类型或操作符之上创造一个新的类型,并将一个标识符绑定到新类型上。
新的类型被称为被定义的类型。与别的类型,包括创建出它的类型,都不一样。

type (
  Point struct{x,y float32} // Point和struct{x,y float32}是两个不同的类型
  polar Point  // polar和Point也是两个不同类型
)
type Block interface{
	BlockSize() int
	Encrypt(src, dst []byte)
	Decrypt(src, dst []byte)
}

被定义的类型可以有相关联的方法。它不继承给定类型的方法,但接口类型的方法集和组合类型的元素依然保留。

// Mutex是一个有两个方法(Lock和Unlock)的数据类型
type Mutex struct{/*Mutex的字段*/}
func (*Mutex)Lock(){/*Lock的实现*/}
func (*Mutex)Unlock(){/*Unlock的实现*/}

// NewMutex与Mutex有相同的组件但方法集是空的
type NewMutex Mutex
// PtrMutex的方法集是空的
type PtrMutex *Mutex
// PrintableMutex具有Lock和Unlock方法,因为是从字段Mutex中提升的。
PrintableMutex struct{
    Mutex
}

// MyBlock是一个接口类型,与Block有一样的方法集
type MyBlock Block

变量声明

变量声明创建一个或多个变量,并将相应的标识符绑定到它们,然后赋给类型和初值。

var i int
var U,V,W float64
var k = 0
var x,y float32= -1, -2
var (
  i int
  u, v, s=2.0, 3.0, "bar"
)
var _, found = entries[name] // 映射查找,只关心结果值found

短变量声明

i, j := 0, 10
f := func() int { return 7 }
ch := make(chan int)
r, w := os.Pipe(fd)  // os.Pipe() returns two values
_, y, _ := coord(p)  // coord() returns three values; only interested in y coordinate

与常规变量声明不同的是,短变量声明可以对变量重新声明,前提是在同一个块中(如果块是函数体,也可以在参数列表)类型不变,并且含有一个新的非空变量。即是说变量的重声明只能出现在多变量短声明中。重新声明并不引入新的变量,只是给原来的变量赋了一个新值。
短变量声明只能在函数中出现。在诸如if、for、switch语句的初始化中,可用于声明本地临时变量。

函数声明

方法声明

猜你喜欢

转载自blog.csdn.net/finalday/article/details/84937967
今日推荐