美文网首页
golang里的变量问题

golang里的变量问题

作者: tonnyzhang | 来源:发表于2021-03-12 09:41 被阅读0次

    我们在使用golang时,是否遇到过以下写法:

    package main
    
    import "fmt"
    
    func fn() (string, error) {
        return "test", fmt.Errorf("test error")
    }
    
    func main() {
        name := "main"
        if name, err := fn(); err != nil {
            fmt.Println("fn return name = ", name, err)
        }
    
        fmt.Println("name = ", name)
    }
    

    上面的输出,有时我们的期望输出为

    fn return name = test, test error
    name = test
    

    但我们得到的输出结果为

    fn return name = test, test error
    name = main
    

    这就是我们今天要说的主角 变量作用域

    在golang中变量作用域分为:

    • 本地局部变量
    • 全局变量
    • 参数变量

    本地局部变量

    定义:在函数或者在语义块(if/for等)中定义的变量
    生效范围:定义在函数里面则在整个函数范围有效; 定义在语义块,则在整个语义块生效

    func main() {
      name := "main"  // main函数内的局部变量
      if true {
          name := "in if"      // 条件语义块中定义的变量
      }
    
      for .... {
        name := "in for"      // for 语义块中定义的变量
      }
      {
        name := "in block"    // 普通语义块中定义的变量
      }
    }
    

    从上面几种情况看,局部变量的定义范围就是看所在的 {} 的范围

    全局变量

    定义:函数外部定义的变量都属于全局变量;全局变量声明必须以 var 开头
    生效范围:当前 package 内,如果想要其他 package 访问,全局变量以大写开头

    package main
    
    var name = "这里定义的为本包的全局变量"
    var Name = "这里定义的为可以包外访问的全局变量"
    func main() {
    }
    

    参数变量

    定义:函数调用时传递的变量
    生效范围:函数范围(但是有可能会可变传入参数的值,取决于传递的参数的类型)
    如果传入的为基本数据类型byte、bool、int、int8、int16、int32、int64、uint、uint8、uint16、uint32、uint64、float32、float64、stringstruct、slice 时为值传递,生效范围就是本函数;但传入了map、func、指针等类型为地址传递,生效范围就不只传入的函数本身


    再回头分析最上面的案例

    // 这里name为if 语义块中定义的局部变量,所以不会改变 if 语义块外面的值
    if name, err := fn(); err != nil {
        fmt.Println("fn return name = ", name, err)
    }
    

    我们可以通过以下代码让其生效

    package main
    
    import "fmt"
    
    func fn() (string, error) {
        return "test", fmt.Errorf("test error")
    }
    
    func main() {
        name := "main"
        var err error
        
        // 这里直接赋值,没有产生新的定义
        if name, err = fn(); err != nil {
            fmt.Println("fn return name = ", name, err)
        }
    
        fmt.Println("name = ", name)
    }
    

    相关文章

      网友评论

          本文标题:golang里的变量问题

          本文链接:https://www.haomeiwen.com/subject/kelnfltx.html