返回顶部
首页 > 资讯 > 精选 >Go语言中的作用域和变量怎么隐藏
  • 821
分享到

Go语言中的作用域和变量怎么隐藏

2023-06-30 11:06:20 821人浏览 独家记忆
摘要

这篇文章主要介绍“Go语言中的作用域和变量怎么隐藏”,在日常操作中,相信很多人在Go语言中的作用域和变量怎么隐藏问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Go语言中的作用域和变量怎么隐藏”的疑惑有所帮助!

这篇文章主要介绍“Go语言中的作用域和变量怎么隐藏”,在日常操作中,相信很多人在Go语言中的作用域和变量怎么隐藏问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Go语言中的作用域和变量怎么隐藏”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

    前言

    变量隐藏在 Go 中可能会令人困惑,让我们尝试弄清楚。

    package mainimport ("fmt""io/ioutil""log")func main() {f, err := ioutil.TempFile("", "")if err != nil {log.Fatal(err)}defer f.Close()if _, err := f.Write([]byte("Hello World\n")); err != nil {log.Fatal(err)} else {fmt.Println("All success")}}

    请注意,我们首先从 TempFile 函数创建了两个变量: f 和 err 。然后我们调用 Write 丢弃写入的字节数。我们让函数在 if 语句中调用它。让我们编译,它工作正常。

    $ go run main.goAll success

    现在,与 if 之外的 Write 调用相同的代码:

    package mainimport ("fmt""io/ioutil""log")func main() {f, err := ioutil.TempFile("", "")if err != nil {log.Fatal(err)}defer f.Close()// if _, err := f.Write([]byte("Hello World\n")); err != nil {// log.Fatal(err)// } else {// fmt.Println("All success")// }_, err := f.Write([]byte("Hello World\n"))if err != nil {log.Fatal(err)} else {fmt.Println("All success")}}

    运行该代码:

    $ go run main.go# command-line-arguments./main.go:23:9: no new variables on left side of :=

    所以发生了什么事?

    请注意,我们使用 := 调用 Write ,这意味着我们创建了一个新变量 err 。在第二个例子中,很明显, err 已经存在,所以我们不能重新声明它。

    但是为什么它第一次起作用呢?因为在 Go 中,变量是其作用域的本地变量。在第一个示例中,我们实际上在 if 范围内隐藏了 err 。

    例如:

    package mainfunc main() {var err error_ = errvar err error_ = err}

    这显然会失败,但是,如果我们限定第二个 err ,它会起作用!

    package mainfunc main() {var err error_ = err{var err error_ = err}}

    包隐藏

    考虑以下代码:

    package mainimport "fmt"func Debugf(fmt string, args ...interface{}) {fmt.Printf(fmt, args...)}

    起初,它看起来不错。我们从 fmt 包中调用 Printf 并将 fmt 变量传递给它。

    函数声明中的 fmt 字符串实际上隐藏了包,现在“只是”一个变量。编译器会抱怨:我们需要使用不同的变量名来保存对 fmt 包的访问。

    全局变量

    需要考虑的是,一个函数已经是一个“子作用域”,它是全局作用域内的一个作用域。这意味着您在函数中声明的任何变量都可以在全局范围内隐藏某些内容。

    正如我们之前看到的,变量可以映射包,全局变量和函数的概念是相同的。

    类型强制

    就像我们可以用变量或函数来映射一个包一样,我们也可以用任何类型的新变量来映射一个变量。阴影变量不需要来自同一类型。这个例子编译得很好:

    package mainfunc main() {var a string_ = a{var a int_ = a}}

    闭包

    使用嵌入式函数时,作用域非常重要。函数中使用且未声明的任何变量都是对上层范围的引用。众所周知的使用 goroutine 的例子:

    package mainimport ("fmt""time")func main() {for _, elem := range []byte{'a', 'b', 'c'} {go func() {fmt.Printf("%c\n", elem)}()}time.Sleep(1e9) // Sleeping to give time to the goroutines to be executed.}

    运行该代码:

    $ go run main.goccc

    这不是我们真正想要的。这是因为范围改变了 goroutine 中引用的 elem ,因此在短列表中,它将始终显示最后一个元素。

    为了避免这种情况,有两种解决方案:

    将变量传递给函数

    package mainimport ("fmt""time")func main() {for _, elem := range []byte{'a', 'b', 'c'} {go func(char byte) {fmt.Printf("%c\n", char)}(elem)}time.Sleep(1e9)}

    运行结果:

    $ go run main.go
    a
    c
    b

    在本地范围内创建变量的副本

    package mainimport ("fmt""time")func main() {for _, elem := range []byte{'a', 'b', 'c'} {char := elemgo func() {fmt.Printf("%c\n", char)}()}time.Sleep(1e9)}

    运行该代码,可以得到我们想要的结果:

    Go语言中的作用域和变量怎么隐藏

    当我们将变量传递给函数时,我们实际上将变量的副本发送给以字符形式接收它的函数。因为每个 goroutine 都有自己的副本,所以没有问题。

    当我们复制变量时,我们创建一个新变量并将 elem 的值分配给它。我们在每次迭代中都这样做,这意味着对于每个步骤,我们都会创建一个新变量, goroutine 会引用该变量。每个 goroutine 都有一个对不同变量的引用,并且它也可以正常工作。

    现在,我们知道我们可以隐藏变量,为什么还要更改名称呢?我们可以简单地使用相同的名称,因为它会影响上层范围:

    package mainimport ("fmt""time")func main() {for _, elem := range []byte{'a', 'b', 'c'} {go func(elem byte) {fmt.Printf("%c\n", elem)}(elem)}time.Sleep(1e9)}
    package mainimport ("fmt""time")func main() {for _, elem := range []byte{'a', 'b', 'c'} {elem := elemgo func() {fmt.Printf("%c\n", elem)}()}time.Sleep(1e9)}

    当我们将变量传递给函数时,会发生同样的事情,我们将变量的副本传递给函数,该函数以名称 elem 和正确的值获取它。

    在这个范围内,由于变量被遮蔽,我们无法从上层范围影响元素,所做的任何更改都将仅在此范围内应用。

    当我们复制变量时,和以前一样:我们创建一个新变量并将 elem 的值分配给它。在这种情况下,新变量恰好与另一个变量具有相同的名称,但想法保持不变:新变量 + 赋值。当我们在范围内创建一个具有相同名称的新变量时,我们有效地隐藏了该变量,同时保持它的值。

    := 的情况

    当 := 与多个返回函数(或类型断言、通道接收和映射访问)一起使用时,我们可以在 2 个语句中得到 3 个变量:

    package mainfunc main() {var iface interface{}str, ok := iface.(string)if ok {println(str)}buf, ok := iface.([]byte)if ok {println(string(buf))}}

    在这种情况下, ok 不会被遮蔽,它只是被覆盖。这就是为什么 ok 不能改变类型。但是,在范围内这样做会隐藏变量并允许使用不同的类型:

    package mainfunc main() {var m = map[string]interface{}{}elem, ok := m["test"]if ok {str, ok := elem.(string)if ok {println(str)}}}

    总结

    隐藏可能非常有用,但需要牢记以避免意外行为。它当然是基于案例的,它通常有助于提高可读性和安全性,但也可以减少它。

    在 goroutines 的例子中,因为它是一个简单的例子,它的影子更具可读性,但在更复杂的情况下,最好使用不同的名称来确定你正在修改什么。然而,另一方面,尤其是对于错误,它是一个非常强大的工具。回到我的第一个例子:

    package mainimport ("io/ioutil""log")func main() {f, err := ioutil.TempFile("", "")if err != nil {log.Fatal(err)}defer f.Close()if _, err := f.Write([]byte("hello world\n")); err != nil {err = nil}// err is still the one fORM TempFile}

    在这种情况下,在 if 中隐藏 err 可以保证以前的错误不会受到影响,而如果使用相同的代码,我们在 if 中使用 = 而不是 := ,它不会隐藏变量而是覆盖错误的值。

    到此,关于“Go语言中的作用域和变量怎么隐藏”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注编程网网站,小编会继续努力为大家带来更多实用的文章!

    --结束END--

    本文标题: Go语言中的作用域和变量怎么隐藏

    本文链接: https://lsjlt.com/news/328367.html(转载时请注明来源链接)

    有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

    猜你喜欢
    • Go语言中的作用域和变量怎么隐藏
      这篇文章主要介绍“Go语言中的作用域和变量怎么隐藏”,在日常操作中,相信很多人在Go语言中的作用域和变量怎么隐藏问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Go语言中的作用域和变量怎么隐藏”的疑惑有所帮助!...
      99+
      2023-06-30
    • 详解Go语言中的作用域和变量隐藏
      目录前言包隐藏全局变量类型强制闭包:= 的情况总结前言 变量隐藏在 Go 中可能会令人困惑,让我们尝试弄清楚。 package main import ( "fmt" "io/...
      99+
      2024-04-02
    • Go语言中变量的作用域是什么
      这篇文章给大家介绍Go语言中变量的作用域是什么,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。作用域为已声明标识符所表示的常量、类型、变量、函数或包在源代码中的作用范围。Go 语言中变量可以在三个地方声明:函数内定义的变...
      99+
      2023-06-08
    • go语言变量的作用域是什么
      这篇“go语言变量的作用域是什么”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“go语言变量的作用域是什么”文章吧。go语言变...
      99+
      2023-07-05
    • 详解Go语言变量作用域
      目录局部变量全局变量形式参数初始化局部和全局变量作用域为已声明标识符所表示的常量、类型、变量、函数或包在源代码中的作用范围。 Go 语言中变量可以在三个地方声明: 函数内定...
      99+
      2022-06-07
      详解go语言 GO go语言 作用域 变量
    • 怎么在Go语言中隐藏窗口
      今天小编给大家分享一下怎么在Go语言中隐藏窗口的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。获取窗口句柄在操作窗口之前,需要...
      99+
      2023-07-06
    • Go语言中的变量和常量
      一、变量相关 1.变量声明 C# : int a; Go : var a int; 需要在前面加一个var关键字,后面定义类型 可以使用 var( a int; b string;)...
      99+
      2024-04-02
    • Go语言变量怎么定义和使用
      这篇“Go语言变量怎么定义和使用”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Go语言变量怎么定义和使用”文章吧。在Go语言...
      99+
      2023-07-04
    • Python中怎么隐藏全局变量
      这篇文章给大家介绍Python中怎么隐藏全局变量,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。程序大致是这样的:CONSTANT = 0  def modifyCons...
      99+
      2023-06-17
    • C语言中变量的作用域和生命周期是什么
      这篇文章给大家分享的是有关C语言中变量的作用域和生命周期是什么的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。变量的作用域和生命周期作用域作用域(scope),程序设计概念,通常来说,一段程序代码中所用到的名字并不...
      99+
      2023-06-29
    • go语言中变量怎么声明
      今天小编给大家分享一下go语言中变量怎么声明的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。变量声明方法有:1、使用var来声...
      99+
      2023-07-05
    • Go语言中的常量和变量的定义
      这篇文章主要介绍“Go语言中的常量和变量的定义”,在日常操作中,相信很多人在Go语言中的常量和变量的定义问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Go语言中的常量和变量的...
      99+
      2024-04-02
    • C语言:变量的作用域和生命周期详解
      目录1.全局变量和局部变量2.变量的作用域2-1.声明外部变量的方法3.变量的生命周期4. 局部变量&自动变量总结1.全局变量和局部变量 定义在代码块外部的是全局变量 定义在...
      99+
      2024-04-02
    • html隐藏域的作用是什么
      这篇文章主要介绍“html隐藏域的作用是什么”,在日常操作中,相信很多人在html隐藏域的作用是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”html隐藏域的作用是什么”...
      99+
      2024-04-02
    • Go语言中变量是什么
      在Go语言中,变量是程序运行过程中,内容可以变化(修改)的量; 变量是程序的基本组成单位,是内存中一个数据存储空间的表示,可以通过变量名找到变量值。变量的功能是存储用户的数据,是计算机语言中能储存计算结果或能表示值抽象概念。本教程操作环境:...
      99+
      2023-05-14
      Go go语言 Golang
    • JavaScript中变量和作用域是怎样的
      这期内容当中小编将会给大家带来有关JavaScript中变量和作用域,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。 JavaScript的变量与其他语言的变量有很大区别。...
      99+
      2024-04-02
    • Java中怎么对成员的变量进行隐藏
      这篇文章给大家介绍Java中怎么对成员的变量进行隐藏,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。一、如果子类与父类中有一个相同名称的成员变量,那么子类的成员变量会不会覆盖父类的成员变量?我们看下在的例子:public...
      99+
      2023-05-31
      ava java
    • C语言中的变量作用域、链接和存储期的意义是什么
      小编给大家分享一下C语言中的变量作用域、链接和存储期的意义是什么,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!在c中变量有三种性质:1、存储期限:变量的存储期限决...
      99+
      2023-06-15
    • C语言函数封装及变量的作用域
      目录1. for循环示例2. 模拟实现投票系统。switch3. 计算字符串空格、数字等数据数量4. 字符串转整数。5. 整数转字符串6. 浮点数转字符串7. 字符串转浮点数8. 函...
      99+
      2024-04-02
    • Go语言的变量与常量怎么定义
      这篇文章主要介绍“Go语言的变量与常量怎么定义”,在日常操作中,相信很多人在Go语言的变量与常量怎么定义问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Go语言的变量与常量怎么定义”的疑惑有所帮助!接下来,请跟...
      99+
      2023-07-05
    软考高级职称资格查询
    编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
    • 官方手机版

    • 微信公众号

    • 商务合作