golang里的变量问题

tonnyzhang · · 677 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

我们在使用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)
}

有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:tonnyzhang

查看原文:golang里的变量问题

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

677 次点击  
加入收藏 微博
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传