我们在哪里可以使用Go中的变量范围和阴影?

时间:2016-04-11 15:37:04

标签: go scope lexical-scope shadowing

我发现的一些相关帖子:

还有很多用于变量范围和阴影的用例 任何代码示例或答案将不胜感激。

1 个答案:

答案 0 :(得分:5)

变量范围和阴影:

  

Go使用块进行词法作用:

     
      
  1. 预先声明的标识符的范围是Universe块。
  2.   
  3. 标识符的范围,表示常量,类型,变量或   在顶层声明的函数(但不是方法)(在任何函数之外)   是包块。
  4.   
  5. 导入的包名称的范围   package是包含导入的文件的文件块   宣言。
  6.   
  7. 表示方法的标识符的范围   接收器,函数参数或结果变量是函数体。
  8.   
  9. 在a中声明的常量或变量标识符的范围   函数从ConstSpec或VarSpec(ShortVarDecl   对于短变量声明)并在最里面的末尾结束   包含块。
  10.   
  11. 在a中声明的类型标识符的范围   function从TypeSpec中的标识符开始,到结尾处结束   最里面的包含块   块中声明的标识符可以在内部块中重新声明。
      虽然内部声明的标识符在范围内,但它   表示内部声明声明的实体。
  12.         

    包条款不是声明;包名称没有   出现在任何范围内。其目的是识别属于的文件   相同的包并指定导入的默认包名称   声明。

优点:

  • 由于无法从外部范围访问数据,因此保留了数据完整性

Go中不同形式的变量阴影:

  1. Golang限制变量范围的方法(在语句中使用短手赋值):

    package main
    import "fmt"
    func main() {
        i := 10 //scope: main
        j := 4
        for i := 'a'; i < 'b'; i++ {
            // i shadowed inside this block
            fmt.Println(i, j) //97 4
        }
        fmt.Println(i, j) //10 4
    
        if i := "test"; len(i) == j {
            // i shadowed inside this block
            fmt.Println(i, j) // i= test , j= 4
        } else {
            // i shadowed inside this block
            fmt.Println(i, j) //test 40
        }
        fmt.Println(i, j) //10 4
    }
    
  2. 当“我们需要更多字母”时,这是限制变量范围的好方法。
    当您需要更多局部变量或范围时,这也很有效:

    使用{}对:
    优点:不需要额外的陈述,如if,for,...

    package main
    import "fmt"
    func main() {
        i := 1
        j := 2
        //new scope :
        {
            i := "hi" //new local var
            j++
            fmt.Println(i, j) //hi 3
        }
        fmt.Println(i, j) //1 3
    }
    
  3. 限制变量范围的另一种方法是使用函数调用
    优点:范围限制,输入值类型参数可用于局部变量,
    缺点:调用/返回时间和堆栈使用:如果它没有被编译器优化

    package main
    import "fmt"
    func fun(i int, j *int) {
        i++                //+nice: use as local var without side effect
        *j++               //+nice: intentionally use as global var
        fmt.Println(i, *j) //11 21
    }
    func main() {
        i := 10 //scope: main
        j := 20
        fun(i, &j)
        fmt.Println(i, j) //10 21
    }
    
  4. 另一种方法是遮蔽全局变量

    package main
    import "fmt"
    var i int = 1 //global
    func main() {
        j := 2
        fmt.Println(i, j) //1 2
        i := 10           //Shadowing global var
        fmt.Println(i, j) //10 2
        fun(i, j)         //10 2
    }
    func fun(i, j int) {
        //i := 100        //error: no new variables on left side of :=
        //var i int = 100 //error: i redeclared in this block
        fmt.Println(i, j) //10 2
    }
    
  5. 请参阅:Variable shadowingScope 并且:Declarations and scope