SyMind / learning

路漫漫其修远兮,吾将上下而求索。
10 stars 1 forks source link

Go 语言作用域 #62

Open SyMind opened 1 year ago

SyMind commented 1 year ago

作用域

Go 通过 block 实现词法作用域:

  1. 预声明的标识符作用域是 universe block。
  2. 在顶层(在任何函数之外)声明的常量、类型、变量或函数(不包含方法)的标识符的作用域是 package block。
  3. 导入包的包名作用域是包含导入声明的文件的 file block。
  4. 方法接收者、函数参数或结果变量的标识符的作用域是函数体。
  5. 函数类型参数或由方法接收者声明的标识符的作用域从函数名称后开始,到函数体末尾结束。
  6. 类型参数的标识符的作用域从类型名称之后开始,到 TypeSpec 结束。
  7. 在函数内声明的常量或变量标识符的范围从 ConstSpec 或 VarSpec(用于短变量声明的 ShortVarDecl)的末尾开始,到最里面的 block 的末尾结束。
  8. 在函数内部声明的类型标识符的范围从 TypeSpec 中的标识符开始,到最内层 block 的末尾结束。

在 block 中声明的标识符可以在内部 block 中重新声明。虽然内部声明的标识符在作用域内,但它表示内部声明所声明的实体。

package clause 不是声明;包名称不出现在任何作用域内。其目的是识别属于同一包的文件并为导入声明指定默认的包名称。

Block

一个 block 匹配一个大括号内可能为空的声明和语句序列。

Block = "{" [StatementList](https://go.dev/ref/spec#StatementList) "}" .
StatementList = { [Statement](https://go.dev/ref/spec#Statement) ";" } .

除了源代码中的显式的 block 外,还有隐式的 block:

  1. universe block 包含所有 Go 源代码。
  2. 每个 package 都有一个 package block,其中包含该 package 的所有 Go 源代码。
  3. 每个文件都有一个 file block,其中包含该文件中的所有 Go 源代码。
  4. 每个 "if"、"or" 和 "switch" 语句都被认为在其自己的隐式 block 中。
  5. "switch" 或 "select" 语句中的每个子句都充当隐式 block。