【问题标题】:Where can we use Variable Scoping and Shadowing in Go?我们在哪里可以在 Go 中使用变量作用域和阴影?
【发布时间】:2016-04-11 15:37:04
【问题描述】:

我发现的一些相关帖子:

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

【问题讨论】:

  • 我不太确定你在这里的目的,但也许你可以用这个写一篇不错的博文。
  • 只是有趣和信息丰富的分享,谢谢。

标签: go scope lexical-scope shadowing


【解决方案1】:

变量范围和阴影:

Go 的词法范围是使用块:

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

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

优点:

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

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
    }
    

请参阅:Variable shadowingScope
还有:Declarations and scope

【讨论】:

    猜你喜欢
    • 2019-05-02
    • 2023-03-10
    • 1970-01-01
    • 1970-01-01
    • 2021-05-11
    • 1970-01-01
    • 2011-03-07
    • 1970-01-01
    • 2015-04-12
    相关资源
    最近更新 更多