美文网首页
Go语言中常见100问题-#1 小心变量遮蔽

Go语言中常见100问题-#1 小心变量遮蔽

作者: 数据小冰 | 来源:发表于2024-02-23 15:33 被阅读0次

小心变量遮蔽

变量的作用域是指一个变量可以被引用的地方/范围。换句话说,就是应用程序的一个区域,在该区域内变量是有效的,超出该区域便无效。在Go语言中,在代码块中声明的变量可以在内部代码块中重新声明,这种使用方法称为变量遮蔽/隐藏,注意在使用时要非常小心,否则很容易出现常见的错误。下面通过一个具体的程序例子说明变量遮蔽/隐藏导致的问题,程序中将以两种不同的方式创建 HTTP 客户端,具体采用哪种方式依赖于变量tracing的值。

var client *http.Client
if tracing {
        client, err := createClientWithTracing()
        if err != nil {
                return err
        }
        log.Println(client)
} else {
        client, err := createDefaultClient()
        if err != nil {
                return err
        }
        log.Println(client)
}
// Use client

上面的程序首先定义了一个客户端变量client, 然后在两个内部代码块中使用短变量声明运算符(:=)赋值,虽然赋值给的变量也是client,但是它与外面的client不是同一个,因此,执行上述程序外部的client始终为nil.

NOTE: 上面的代码可以编译通过,因为内部赋值的client变量在log.Println中使用到了,否则的话,将出现编译错误,提示client(内部的)声明但未使用。

如何修复上面代码中存在的问题呢?有两种不同的方法。方法一是在内部代码块中使用一个临时变量保存client,此临时变量名不要使用client,然后再将临时变量值赋值给client, 实现代码如下。这里先将结果保存在临时变量c中,c的作用域在if块中,最后再将c赋值给客户端变量client.

var client *http.Client
if tracing {
        c, err := createClientWithTracing()
        if err != nil {
                return err
        }
        client = c
} else {
        // Same logic
}

方法二是使用赋值运算符(=)将创建结果直接分配给客户端变量client,但是需要创建一个错误变量,因为赋值运算符(=)对已声明的变量才能使用。然后直接将创建结果分配给client,实现如下。

var client *http.Client
var err error
if tracing {
        client, err = createClientWithTracing()
        if err != nil {
                return err
        }
} else {
        // Same logic
}

上述两种方法都是正确的,主要区别在于方法二种只执行了一个赋值操作,阅读起来可能更容易。此外,使用方法二,可以在if/else语句之后统一对错误进行处理。

if tracing {
        client, err = createClientWithTracing()
} else {
        client, err = createDefaultClient()
}
if err != nil {
        // Common error handling
}

总结,在内部代码块中重新声明变量时,会产生变量遮蔽/隐藏,通过前面的例子可以看到这种做法很容易出错。所以在编码中,注重代码品味,尽量不要犯变量遮蔽/隐藏问题。虽然有时重用现有变量会非常方便,例如在用err表示错误时。但是,总体来说,我们应该谨慎小心,否则很容易出现问题,像本文举的例子,接收到值的变量不是我们预期的变量。

相关文章

  • golang的helloworld

    go语言初识 go语言的变量

  • Golang的入门教程(四)

    1: 变量逃逸 堆和栈各有优缺点,该怎么在变成中处理这个问题呢?Go语言将这个过程整合到编译器中,命名为"变量逃逸...

  • Go变量声明

    go变量类型声明 变量短声明go语言是强类型语言所以在变量的声明中制定类型,但是在方法中声明的变量可以不需要关键字...

  • 局部变量和全局变量

    什么是局部变量? 在Go语言和C语言中写在{}中或者函数中或者函数的形参, 就是局部变量 什么是全局变量? 在Go...

  • VSCODE配置go语言开发环境(Windows)

    一、配置GO语言环境** 设置环境变量 环境变量path中添加go安装bin目录 cmd输入go version看...

  • 初识Go语言-1

    Go语言学习路径 初识Go语言 Go语言环境搭建与IDE安装 Go语言基础语法 Go语言数据类型 Go语言变量和常...

  • Go语言学习笔记-变量与作用域

    Go 语言变量的声明 Go 语言是静态类型语言,因此变量 (variable) 是有明确类型的,编译器也会检查变量...

  • go学习笔记(三)——语法

    1.变量 变量是每种语言都不可或缺的声明方式,go提供了以下几种声明方式 需要注意的是,在go语言中声明的变量如果...

  • Go语言 - 变量

    变量是程序中的基本数据单元,用于存储一个可变的数据。Go语言中,变量有其固定的类型。与C语言类似,go语言也是强类...

  • Go语言探索 - 4(原创)

    Go语言基础系列博客用到的所有示例代码 在上一篇文章中,主要学习了Go语言的变量、指针、指针变量、常量以及类型转换...

网友评论

      本文标题:Go语言中常见100问题-#1 小心变量遮蔽

      本文链接:https://www.haomeiwen.com/subject/tcknadtx.html