Go 语言中的变量作用域规则决定了变量在程序的哪些部分是可见的和可以访问的。理解这些规则对于编写清晰、维护性高的代码非常重要。下面是一个系统性的解释。

变量的作用域类型

  1. 包级作用域

    • 包级作用域的变量在整个包内是可见的。使用 varconst 关键字在包级声明的变量就是包级变量。

    • 包级函数也是包级作用域的一部分。

    • 例如:

      package main
      
      var packageVar = "I am package level variable"
      
      func main() {
      fmt.Println(packageVar) // 这里可以访问 packageVar
      }
  2. 函数级作用域

    • 在函数内部声明的变量在整个函数内都是可见的。

    • 这些变量的作用范围从声明开始到函数末尾。

      package main
      
      func main() {
      var functionVar = "I am function level variable"
      fmt.Println(functionVar) // 这里可以访问 functionVar
      }
  3. 局部作用域

    • 局部变量是在代码块(如 ifforswitch 语句)内声明的,作用范围仅限于该代码块内。

    • 局部变量的生命周期从声明开始,到包含它的代码块结束。

      package main
      
      func main() {
      if true {
      var blockVar = "I am block level variable"
      fmt.Println(blockVar) // 这里可以访问 blockVar
      }
      // fmt.Println(blockVar) // 这里访问 blockVar 会导致编译错误
      }
  4. 全局作用域

    • Go 语言没有真正意义上的全局变量。包级变量虽然可以被包内的所有文件访问,但不能跨包直接访问。如果需要跨包访问,需要使用大写字母开头的标识符并通过包导入访问。

特殊作用域规则

  1. 变量遮蔽

    • 内层作用域可以声明与外层作用域同名的变量,内层变量会遮蔽(覆盖)外层变量的访问。

    • 这不会影响外层变量的值,但在内层作用域中外层变量不可见。

      package main
      
      var x = "package level"
      
      func main() {
      x := "function level"
      {
      var x = "block level"
      fmt.Println(x) // 输出 "block level"
      }
      fmt.Println(x) // 输出 "function level"
      }
  2. 短变量声明(:=)

    • 在函数内部可以使用 := 进行短变量声明,它只能在函数级或更内层作用域中使用。

    • 如果在同一个代码块内重复声明,会导致编译错误。

      package main
      
      func main() {
      x := 1
      if x := 2; x > 1 {
      fmt.Println(x) // 输出 2
      }
      fmt.Println(x) // 输出 1
      }

特殊语句的作用域

  1. if, else if, else 语句

    • ifelse 块各自有自己的作用域。在 ifelse if 块中声明的变量在对应的块内是有效的。

      package main
      
      func main() {
      if a := 1; a == 1 {
      fmt.Println("a is 1")
      }
      // fmt.Println(a) // 这里访问 a 会导致编译错误
      } package main if a := 1; a != 1 {
      fmt.Println("a is 1")
      } else {
      fmt.Println(a) // 这里访问 a 不会导致编译错误
      }
  2. for 语句

    • for 循环中声明的变量作用域仅限于循环体内。

      package main
      
      func main() {
      for i := 0; i < 3; i++ {
      fmt.Println(i)
      }
      // fmt.Println(i) // 这里访问 i 会导致编译错误
      }
  3. switch 语句

    • switch 和每个 case 块中声明的变量作用域是相互独立的。

      package main
      
      func main() {
      switch n := 1; n {
      case 1:
      var x = 1
      fmt.Println(x) // 输出 1
      case 2:
      // fmt.Println(x) // 这里访问 x 会导致编译错误
      }
      }

接口类型和变量作用域

接口变量的作用域遵循上述规则,但需要注意接口变量的底层实现和值的关系,这在之前讨论的例子中已经详细说明。

通过理解这些作用域规则,可以更好地管理变量的生命周期和可见性,从而编写更高效和可维护的代码。

go语言中变量的作用域的更多相关文章

  1. C/C++——C++变量的作用域与生命周期,C语言中变量的作用域和生命周期

    全局变量 作用域:全局作用域(全局变量只需在一个源文件中定义,就可以作用于所有的源文件.) 生命周期:程序运行期一直存在 引用方法:其他文件中要使用必须用extern 关键字声明要引用的全局变量. 内 ...

  2. C语言中变量的作用域和生命周期

    变量的类型: 1. 局部变量和全局变量 局部变量也称为内部变量. 局部变量是在函数内作定义说明的.其作用域仅限于函数内, 离开该函数后再 使用这种变量是非法的. 全局变量也称为外部变量,它是在函数外部 ...

  3. C语言中变量、全局变量与变量的作用域

    什么是变量: 变量常量都是表征数据的一种形式:常量用来表示数据的值: 变量不仅可以用来表示数据的值:还可以用来存放数据:因为变量对应着一定的内存单元: 变量和常量必须先定义后使用. 变量名和常量名都是 ...

  4. C/C++语言中变量作用域:局部变量,全局变量,文件级变量

    C/C++语言中的变量分为全局变量和局部变量. 这样的划分方式的根据是变量的可见范围或者叫做作用域. 1 局部变量 局部变量指的是定义在{}中的变量,其作用域也在这个范围内.尽管常见的局部变量都是定义 ...

  5. C语言中变量和函数的作用域和链接属性

    C语言中变量和函数的作用域和链接属性 作用域 代码块作用域: 代码块指的是使用"{}"包围起来的部分. 在代码块中定义的变量,代码块之外是不能访问的. 代码块嵌套之后的变量作用域, ...

  6. Python中变量的作用域(variable scope)

    http://www.crifan.com/summary_python_variable_effective_scope/ 解释python中变量的作用域 示例: 1.代码版 #!/usr/bin/ ...

  7. 注意for循环中变量的作用域-乾颐堂

    1 2 for e in collections:     pass 在for 循环里, 最后一个对象e一直存在在上下文中.就是在循环外面,接下来对e的引用仍然有效. 这里有个问题容易被忽略,如果在循 ...

  8. 注意for循环中变量的作用域

    for e in collections: pass 在for 循环里, 最后一个对象e一直存在在上下文中.就是在循环外面,接下来对e的引用仍然有效. 这里有个问题容易被忽略,如果在循环之前已经有一个 ...

  9. c语言中变量和函数作用域深究

    首先,函数的作用域和访问权限基本可以参考 C语言中的作用域,链接属性和存储类型 也存在例外情况,比如内联函数 static inline,使用static 修饰 inline之后外部文件也可以访问内联 ...

  10. JavaScript 中变量、作用域和内存问题的学习

    这是我学习JavaScript的第二篇文章,之前做过几年的Java开发,发现JavaScript虽然也是面向对象的语言但是确实有很多不同之处.就本篇博客,主要学习总结一下最近学习到的JavaScrip ...

随机推荐

  1. python性能分析器:cProfile

    代码: (1) import cProfile import re cProfile.run('re.compile("foo|bar")') 运行结果: (2) import c ...

  2. 国内网友搭建的 Huggingface 镜像站 —— https://hf-mirror.com/

    huggingface是什么这里不作解释. hugggingface的网站访问同Google一样,不能直接通过浏览器访问,需要科学的方式才可以,这里假设大家是知道如何访问Google的: huggin ...

  3. 实现一个终端文本编辑器来学习golang语言:第三章文本查看器part1

    本章我们来完成文本编辑器的文件打开和查看功能,最后成品如上图.我们将分4步,逐渐完成本章所需功能.内容比较多,会分为两个部分,第一部分主要关注于"View视图"和"buf ...

  4. 零基础学习人工智能—Python—Pytorch学习(一)

    前言 其实学习人工智能不难,就跟学习软件开发一样,只是会的人相对少,而一些会的人写文章,做视频又不好好讲. 比如,上来就跟你说要学习张量,或者告诉你张量是向量的多维度等等模式的讲解:目的都是让别人知道 ...

  5. div构建table

    1.Css display值与解释-(详细可见CSS手册的CSS display手册)参数:block :块对象的默认值.用该值为对象之后添加新行none :隐藏对象.与visibility属性的hi ...

  6. MySQL数据库基本操作以及使用

    MySQL数据库 操纵数据库 查看数据库 show databases; 创建数据库 create database <database_name>; 删除数据库 drop databas ...

  7. Es java API官网手册

    官方地址: 一.TransportClient客户端 https://www.elastic.co/guide/en/elasticsearch/client/java-api/7.5/index.h ...

  8. 新一代监控神器Prometheus+Grafana介绍及使用

    一.介绍 1.什么是Prometheus? 普罗米修斯是一个开源的系统监控及报警工具,在2016年加入了 Cloud Native Computing Foundation,是继Kubernetes之 ...

  9. STL 改造红黑树 模拟封装set和map

    改造红黑树 目录 改造红黑树 适配STL迭代器的红黑树 基本结构 RBTreeNode __RBTree_iterator RBTree 完整代码 封装的set 封装的map 在初次看STL中实现红黑 ...

  10. idea 的Tomcat 的简单配置

    不限速网盘下载: https://kohler.lanzouv.com/iSSfc0akw3vc 官网下载: https://tomcat.apache.org/download-80.cgi 正常解 ...