Go 语言中的变量作用域范围

栏目: IT技术 · 发布时间: 4年前

内容简介:代码清单 4-6 展示的程序能够生成并显示一个随机的日期(这个日期也许就是我们启程去火星的日期)。 除此之外,这个程序还演示了 Go 中的几种不同的作用域,并阐明了在声明变量时考虑作用域的重要性。代码清单 4-6 变量作用域规则:因为

Note

本文摘录自《Go语言趣学指南》第 4 章, 请访问 gpwgcn.com 以获取更多相关信息。

Go 语言中的变量作用域范围

代码清单 4-6 展示的程序能够生成并显示一个随机的日期(这个日期也许就是我们启程去火星的日期)。 除此之外,这个程序还演示了 Go 中的几种不同的作用域,并阐明了在声明变量时考虑作用域的重要性。

代码清单 4-6 变量作用域规则: scope-rules.go

package main

import (
    "fmt"
    "math/rand"
)

var era = "AD"      // era 变量在整个包都是可用的。

func main() {
    year := 2018    // era 变量和 year 变量都处于作用域之内。

    switch month := rand.Intn(12) + 1; month {  // 变量 era 、year 和 month 都处于作用域之内。
    case 2:
        day := rand.Intn(28) + 1                // 变量 era 、year 、month 和 day 都处于作用域之内。
        fmt.Println(era, year, month, day)
    case 4, 6, 9, 11:
        day := rand.Intn(30) + 1                // 这两个 day 变量是全新声明的变量,跟上面声明的同名变量并不相同。
        fmt.Println(era, year, month, day)
    default:
        day := rand.Intn(31) + 1                // 这两个 day 变量是全新声明的变量,跟上面声明的同名变量并不相同。
        fmt.Println(era, year, month, day)
    }   // month 变量和 day 变量不再处于作用域之内。
}       // year 变量不再处于作用域之内。

因为 era 变量的声明位于 main 函数之外的 包作用域 中,所以它对于 main 包中的所有函数都是可见的。

Note

因为包作用域不允许使用简短声明, 所以我们无法在这个作用域中使用 era := "AD" 来进行声明。

year 变量只在 main 函数中可见。 如果包中还存在着其他函数,那么它们将会看见 era 变量,但是却无法看到 year 变量。 函数作用域 比包作用域要狭窄,它起始于 func 关键字,并终结于函数声明的右大括号。

month 变量在整个 switch 语句的任何位置都可见,不过一旦 switch 语句结束, month 就不再处于作用域之内了。 switch 语句的作用域始于 switch 关键字,并终结于 switch 语句的右大括号。

因为 switch 的每个 case 分支都拥有自己独立的作用域,所以三个分支分别拥有三个独立的 day 变量。 在每个分支结束之后,该分支声明的 day 变量将不再处于作用域之内。 switch 分支的作用域是唯一一种无需使用大括号标识的作用域。

代码清单 4-6 中的代码距离完美还有相当远的一段距离。 变量 monthday 狭窄的作用域导致 Println 重复出现了三次,这种代码重复可能会引发修改,并因此导致错误。 比如说,我们可能会决定不再在每个分支中都打印 era 变量,但是却忘记了修改某个分支。 在某些情况下,出现代码重复是正常的,但这种情况通常被认为是代码的 坏味道 ,需要谨慎地处理。

为了消除重复并简化代码,我们需要将代码清单 4-6 中的某些变量声明移动到范围更宽广的函数作用域中,使得这些变量可以在 switch 语句结束之后继续为程序所用。 为此,我们需要对代码实施 重构 ,也即是在不改变代码行为的基础上对代码进行修改。 重构得出的代码清单 4-7 跟之前的代码行为完全相同,它们都可以选取并打印出随机的日期。

代码清单 4-7 重构后的随机日期选取程序: random-date.go

package main

import (
    "fmt"
    "math/rand"
)

var era = "AD"

func main() {
    year := 2018
    month := rand.Intn(12) + 1
    daysInMonth := 31

    switch month {
    case 2:
        daysInMonth = 28
    case 4, 6, 9, 11:
        daysInMonth = 30
    }

    day := rand.Intn(daysInMonth) + 1
    fmt.Println(era, year, month, day)
}

尽管狭窄的作用域有助于减少脑力负担,但代码清单 4-6 的例子也表明了过分约束变量将 损害 代码的可读性。 在遇到这种问题的时候,我们应该根据具体情况逐步实施重构,直到代码的可读性能够满足我们的要求为止。


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

SQL完全手册

SQL完全手册

格罗夫 / 电子工业 / 2006-6 / 68.00元

本书为专业和非专业用户、程序员、数据处理方面的专业人士和希望理解sQL在今天计算机产业中的影响的经理们提供了关于SQL语言的全面深入的介绍。本书为理解和使用SQL提供了一个概念上的框架,描述了SQL的历史和SQL的标准,解释了SQL在各种计算机产业领域(如企业级数据处理、数据仓库、Web站点体系结构)中的作用。这一版包含一些新的章节,专门讲述SQL在应用服务器体系结构中的作用、sQL与xML的集成......一起来看看 《SQL完全手册》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

随机密码生成器
随机密码生成器

多种字符组合密码

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器