我们在哪里可以在 Go 中使用可变范围和阴影? [英] Where can we use Variable Scoping and Shadowing in Go?

查看:17
本文介绍了我们在哪里可以在 Go 中使用可变范围和阴影?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我发现的一些相关帖子:

Some related posts I've found:

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

Also there are many use cases to Variable Scoping and Shadowing.
Any code samples or answers will be appreciated.

推荐答案

变量范围和阴影:

Go 的词法范围使用块:

Go is lexically scoped using blocks:

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

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

The package clause is not a declaration; the package name does not appear in any scope. Its purpose is to identify the files belonging to the same package and to specify the default package name for import declarations.

优点:

  • 由于无法从外部范围访问数据,因此保留了数据完整性
    1. Golang 限制变量作用域的方法(在语句中使用简写赋值):

    1. Golang way to limit variable scope (using short-hand assignment inside statements):

    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
    }
    

  • 当我们需要更多字母"时,这是限制变量范围的好方法.
    当您需要更多局部变量或范围时,这也很有效:

  • When "we need more alphabets", this is nice way to limit variables scope.
    Also this works well when you need more local variables or scope:

    使用 {} 对:
    优点:不需要额外的语句,如 if、for、...

    using { and } pair:
    Pros: no need to extra statements like 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
    }
    

  • 另一种限制变量范围的方法是使用函数调用:
    优点:范围限制,输入值类型参数可以像局部变量一样使用,
    缺点:调用/返回时间,以及堆栈使用:如果没有被编译器优化

  • Another way to limit variable scope is using function calls:
    Pros: scope limit, input value type parameters are usable like local variables,
    Cons: call/return time, and stack usage: if it is not optimized by compiler

    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
    }
    

  • 另一种方法是隐藏全局变量:

    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
    }
    

  • 参见:变量阴影范围.
    并且:声明和范围:

    这篇关于我们在哪里可以在 Go 中使用可变范围和阴影?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆