广告位联系
返回顶部
分享到

Go语言的常量、枚举、作用域介绍

python 来源:互联网 作者:佚名 发布时间:2024-07-25 21:52:39 人浏览
摘要

常量 常量类似于变量,但其初始值不能更改。在需要代码运行时保持不变的值的情况下,使用常量非常有用。虽然可以将这些值硬编码到代码中以实现类似效果,但经验表明,虽然这些值在运

常量

常量类似于变量,但其初始值不能更改。在需要代码运行时保持不变的值的情况下,使用常量非常有用。虽然可以将这些值硬编码到代码中以实现类似效果,但经验表明,虽然这些值在运行时不需要更改,但将来可能需要更改。如果发生这种情况,追踪和修复所有硬编码的值可能是一项繁琐且容易出错的任务。使用常量可以节省大量的后续维护工作。

常量声明类似于 var 语句。定义常量时,必须指定初始值。类型是可选的,如果省略,类型将会被推断。初始值可以是文字值或简单的表达式,并且可以使用其他常量的值。与 var 一样,可以在一个语句中声明多个常量。以下是常量声明的语法:

1

2

3

4

5

6

7

const <name> <type> = <value>

const (

  <name1> <type1> = <value1>

  <name2> <type2> = <value2>

  …

  <nameN> <typeN> = <valueN>

)

练习 1.16 – 常量

在这个练习中,我们遇到了一个性能问题:我们的数据库服务器太慢了。我们将创建一个自定义内存缓存。我们会使用 Go 的 map 集合类型作为缓存。缓存中可以存储的项目数量有一个全局限制。我们将使用一个 map 来帮助跟踪缓存中的项目数量。我们需要缓存两种类型的数据:书籍和 CD。两者都使用 ID,因此我们需要一种方法来区分共享缓存中的两种类型的项目。我们需要一种方法来设置和获取缓存中的项目。

我们将设置缓存中的最大项目数量。我们还将使用常量添加前缀,以区分书籍和 CD。让我们开始吧:

创建一个新的文件夹,并在其中添加一个 main.go 文件。

在 main.go 文件的顶部添加 main 包名:

1

package main

导入我们需要的包:

1

import "fmt"

创建一个表示全局限制大小的常量:

1

const GlobalLimit = 100

创建一个 MaxCacheSize 常量,它是全局限制大小的 10 倍:

1

const MaxCacheSize int = 10 * GlobalLimit

创建我们的缓存前缀:

1

const (  CacheKeyBook = "book_"  CacheKeyCD = "cd_")

声明一个 map 类型的变量,用于存储缓存,其中键和值都是字符串类型:

1

var cache map[string]string

创建一个从缓存中获取项目的函数:

1

2

3

func cacheGet(key string) string {

  return cache[key]

}

创建一个在缓存中设置项目的函数:

1

func cacheSet(key, val string) {

在这个函数中,检查 MaxCacheSize 常量,防止缓存超过这个大小:

1

2

3

4

5

  if len(cache)+1 >= MaxCacheSize {

    return

  }

  cache[key] = val

}

创建一个从缓存中获取书籍的函数:

1

func GetBook(isbn string) string {

使用书籍缓存前缀创建一个唯一的键:

1

2

  return cacheGet(CacheKeyBook + isbn)

}

创建一个将书籍添加到缓存中的函数:

1

func SetBook(isbn string, name string) {

使用书籍缓存前缀创建一个唯一的键:

1

2

  cacheSet(CacheKeyBook+isbn, name)

}

创建一个从缓存中获取 CD 数据的函数:

1

func GetCD(sku string) string {

使用 CD 缓存前缀创建一个唯一的键:

1

2

  cacheSet(CacheKeyCD+sku, title)

}

创建一个将 CD 添加到共享缓存中的函数:

1

func SetCD(sku string, title string) {

使用 CD 缓存前缀常量为共享缓存构建一个唯一的键:

1

2

  cacheSet(CacheKeyCD+sku, title)

}

创建 main() 函数:

1

func main() {

通过创建一个 map 值来初始化缓存:

1

2

  cache = make(map[string]string)

}

将一本书添加到缓存中:

1

SetBook("1234-5678", "Get Ready To Go")

将 CD 添加到缓存中:

1

SetCD("1234-5678", "Get Ready To Go Audio Book")

从缓存中获取并打印那本书:

1

fmt.Println("Book :", GetBook("1234-5678"))

从缓存中获取并打印那张 CD:

1

fmt.Println("CD :", GetCD("1234-5678"))

关闭 main() 函数:

}

保存文件。然后,在新文件夹中运行:

1

go run .

预期输出

在这个练习中,我们使用常量来定义在代码运行时不需要更改的值。我们用不同的语法选项声明了常量,有的指定了类型,有的则没有。我们既声明了单个常量,也在一个语句中声明了多个常量。

接下来,我们将查看与常量相关的变体,用于更紧密关联的值。

枚举

枚举是一种定义固定值列表的方式,这些值都是相关的。虽然 Go 语言没有内置的枚举类型,但它提供了 iota 工具,让我们可以使用常量定义自己的枚举。接下来,我们将探讨如何使用 iota 来实现枚举。

例如,在以下代码中,我们将一周的天数定义为常量。这个代码很适合使用 Go 的 iota 特性:

1

2

3

4

5

6

7

8

9

10

11

const (

  Sunday  = 0

  Monday  = 1

  Tuesday = 2

  Wednesday = 3

  Thursday = 4

  Friday  = 5

  Saturday = 6

)

使用 iota,Go 会帮助我们管理这样的列表。使用 iota,以下代码等同于上面的代码:

1

2

3

4

5

6

7

8

9

10

11

const (

  Sunday = iota

  Monday

  Tuesday

  Wednesday

  Thursday

  Friday

  Saturday

)

通过 iota,我们可以自动为枚举分配值。使用 iota 使得创建和维护枚举更加方便,特别是在你需要在代码中间添加新值时。iota 是一个标识符,指示 Go 编译器从 0 开始为第一个值分配,后续值每次递增 1。在使用 iota 时,顺序是重要的。iota 还允许跳过值(使用 _),从不同的偏移量开始,甚至使用更复杂的计算。

接下来,我们将详细了解 Go 的变量作用域规则以及这些规则如何影响代码编写。

作用域

在 Go 中,所有变量都存在于一个作用域中。顶级作用域是包作用域。作用域可以包含子作用域。定义子作用域的方式有几种;最简单的理解方式是,当你看到 { 时,表示你开始了一个新的子作用域,而这个子作用域在遇到匹配的 } 时结束。父子关系是在代码编译时定义的,而不是在代码运行时。当访问变量时,Go 会查看变量定义的作用域。如果在当前作用域找不到该变量,Go 会查看父作用域,然后是祖父作用域,一直到包作用域。当找到匹配的变量时,Go 会停止查找。如果没有找到匹配的变量,则会报错。

换句话说,当你的代码使用一个变量时,Go 需要确定该变量的定义位置。它从当前代码的作用域开始查找。如果在该作用域内找到一个变量定义,则停止查找并使用该变量定义。如果找不到变量定义,则开始向上遍历作用域栈,直到找到具有该名称的变量。这个查找过程基于变量名称。如果找到的变量名称匹配但类型不正确,Go 会抛出错误。

在以下示例中,我们定义了一个 level 变量。无论在哪里使用 level,都会使用同一个变量:

1

2

3

4

5

6

7

8

9

10

11

12

13

package main

import "fmt"

var level = "pkg"

func main() {

  fmt.Println("Main start :", level)

  if true {

    fmt.Println("Block start :", level)

    funcA()

  }

}

func funcA() {

  fmt.Println("funcA start :", level)

}

输出结果如下:

Main start : pkg
Block start : pkg
funcA start : pkg

在这个示例中,我们创建了一个 level 的影子变量。这个新的 level 变量与包作用域中的 level 变量没有关系。当我们在块内打印 level 时,Go 运行时会在 main 的作用域中找到 level 变量,并停止查找。这导致新变量覆盖了包变量。你也可以看到它是一个不同的变量,因为它的类型不同,变量在 Go 中不能改变类型:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

package main

import "fmt"

var level = "pkg"

func main() {

  fmt.Println("Main start :", level)

  // 创建一个影子变量

  level := 42

  if true {

    fmt.Println("Block start :", level)

    funcA()

  }

  fmt.Println("Main end :", level)

}

func funcA() {

  fmt.Println("funcA start :", level)

}

输出结果如下:

Main start : pkg
Block start : 42
funcA start : pkg
Main end : 42

Go 的静态作用域解析在调用 funcA 时发挥作用。因此,当 funcA 运行时,它仍然看到包作用域中的 level 变量。作用域解析不考虑 funcA 的调用位置。

你不能访问子作用域中定义的变量:

1

2

3

4

5

6

7

8

9

10

package main

import "fmt"

func main() {

  {

    level := "Nest 1"

    fmt.Println("Block end :", level)

  }

  // 错误:未定义: level

  //fmt.Println("Main end  :", level)

}


版权声明 : 本文内容来源于互联网或用户自行发布贡献,该文观点仅代表原作者本人。本站仅提供信息存储空间服务和不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权, 违法违规的内容, 请发送邮件至2530232025#qq.cn(#换@)举报,一经查实,本站将立刻删除。

您可能感兴趣的文章 :

原文链接 :
相关文章
  • 使用Python批量移除Word文档水印的代码

    使用Python批量移除Word文档水印的代码
    Word文档被广泛用于各种正式与非正式的沟通场合。有时候这些文档中可能包含着不再需要的水印,比如早期的草稿标记、保密声明或是仅供
  • Go语言的常量、枚举、作用域介绍
    常量 常量类似于变量,但其初始值不能更改。在需要代码运行时保持不变的值的情况下,使用常量非常有用。虽然可以将这些值硬编码到代
  • Pandas中DataFrame.replace()函数的实现
    DataFrame.replace()函数用于替换DataFrame中的指定值。该函数允许使用单个值、列表、字典或正则表达式进行替换操作,非常灵活。 二、语法和参
  • pandas中8种常用的index索引设置

    pandas中8种常用的index索引设置
    在数据处理时,经常会因为index报错而发愁。不要紧,本次来和大家聊聊pandas中处理索引的几种常用方法。 1.读取时指定索引列 很多情况下
  • Pandas设置DataFrame的index索引起始值为1的两种方法

    Pandas设置DataFrame的index索引起始值为1的两种方法
    导入数据 1 2 3 4 5 6 7 8 9 import pandas as pd df = pd.DataFrame([[liver,E,89,21,24,64], [Arry,C,36,37,37,57], [Ack,A,57,60,18,84], [Eorge,C,93,96,71,78], [Oah,D,65,49,61,86] ],
  • Python读取URL生成PDF的方法

    Python读取URL生成PDF的方法
    1. 安装依赖的exe 需要在这个网址,安装一个exe包,地址:https://wkhtmltopdf.org/ 进入网址后,点这个位置: 选择一个你的操作系统的下载链接
  • 使用Python自动化创建和扫描二维码

    使用Python自动化创建和扫描二维码
    二维码(Quick Response code)已成为在物理和数字领域之间架起桥梁的多功能工具。从分享联系信息和网站链接到促进支付和跟踪库存,二维码
  • Pandas库中isnull函数的实现
    一、简介 isnull()是Pandas库中DataFrame和Series对象的一个函数,用于检测数据中的缺失值。它返回一个布尔类型的DataFrame或Series,其中True表示该
  • Pandas库中ffill函数的具体使用
    一、简介 ffill(forward fill)是Pandas库中DataFrame和Series对象的一个函数,用于填充缺失值(NaN)。它通过使用前面的有效值来填充后续的缺失
  • Pandas库中dataframe.corr()函数的使用
    一、简介 dataframe.corr()是Pandas库中的一个函数,用于计算DataFrame中各列之间的相关系数。相关系数衡量的是两个变量之间线性关系的强度和方
  • 本站所有内容来源于互联网或用户自行发布,本站仅提供信息存储空间服务,不拥有版权,不承担法律责任。如有侵犯您的权益,请您联系站长处理!
  • Copyright © 2017-2022 F11.CN All Rights Reserved. F11站长开发者网 版权所有 | 苏ICP备2022031554号-1 | 51LA统计