关于golang类型推断和变量重声明详解

 更新时间:2023年08月10日 09:56:27   作者:m旧裤子  
在Go语言中,类型推断可以根据变量的初始化值自动推断出变量的类型,而不需要显式地声明变量类型,变量重声明可以在同一作用域内重复声明一个变量,只要其中至少一个是新的变量,本就简单的给大家介绍一下golang类型推断和变量重声明,需要的朋友可以参考下

类型推断是一种编程语言在编译期自动解释表达式类型的能力。

1.Go语言的类型推断可以带来哪些好处?

在写代码时,我们通过使用Go语言的类型推断会节省敲击次数,而节省下来的键盘敲击次数几乎可以忽略不记。但它真正的好处,往往会体现在我们写代码之后的那些事情上,比如代码重构。

我们依然通过调用一个函数在声明name变量的同时为它赋值,但是这个函数不是flag.String,而是由我们自己定义的某个函数,比如叫getTheFlag。

package main
import (
    "flag"
    "fmt"
)
func main() {
    var name = getTheFlag()
    flag.Parse()
    fmt.Printf("Hello, %v!\n", *name)
}
func getTheFlag() *string {
    return flag.String("name", "everyone", "The greeting object.")
}

我们可以用getTheFlag函数包裹(或者说包装)那个对flag.String函数的调用,并把其结果直接作为getTheFlag函数的结果,结果的类型是*string。

这样一来,var name =右边的表达式,可以变为针对getTheFlag函数的调用表达式了。这实际上是对“声明并赋值name变量的那行代码”的重构。

我们通常把不改变某个程序与外界的任何交互方式和规则,而只改变其内部实现”的代码修改方式,叫做对该程序的重构。重构的对象可以是一行代码、一个函数、一个功能模块,甚至一个软件系统。

你会发现,你可以随意改变getTheFlag函数的内部实现,及其返回结果的类型,而不用修改main函数中的任何代码。

这个命令源码文件依然可以通过编译,并且构建和运行也都不会有问题。也许你能感觉得到,这是一个关于程序灵活性的质变。

我们不显式地指定变量name的类型,使得它可以被赋予任何类型的值。也就是说,变量name的类型可以在其初始化时,由其他程序动态地确定。

在你改变getTheFlag函数的结果类型之后,Go 语言的编译器会在你再次构建该程序的时候,自动地更新变量name的类型。

Go 语言是静态类型的,所以一旦在初始化变量时确定了它的类型,之后就不可能再改变。这就避免了在后面维护程序时的一些问题。另外,请记住,这种类型的确定是在编译期完成的,因此不会对程序的运行效率产生任何影响。

Go语言的类型推断可以带来哪些好处?

回答:Go 语言的类型推断可以明显提升程序的灵活性,使得代码重构变得更加容易,同时又不会给代码的维护带来额外负担(实际上,它恰恰可以避免散弹式的代码修改),更不会损失程序的运行效率。

2.变量的重声明是什么意思?

涉及到短变量声明。通过使用它,我们可以对同一个代码块中的变量进行重声明。

在 Go 语言中,代码块一般就是一个由花括号括起来的区域,里面可以包含表达式和语句。Go 语言本身以及我们编写的代码共同形成了一个非常大的代码块,也叫全域代码块。这主要体现在,只要是公开的全局变量,都可以被任何代码所使用。相对小一些的代码块是代码包,一个代码包可以包含许多子代码包,所以这样的代
码块也可以很大。

接下来,每个源码文件也都是一个代码块,每个函数也是一个代码块,每个if语句、for语句、switch语句和select语句都是一个代码块。甚至,switch或select语句中的case子句也都是独立的代码块。走个极端,我就在main函数中写一对紧挨着的花括号算不算一个代码块?当然也算,这甚至还有个名词,叫“空代码块”。

变量重声明的前提条件:

  1. 由于变量的类型在其初始化时就已经确定了,所以对它再次声明时赋予的类型必须与其
    原本的类型相同,否则会产生编译错误。
  2. 变量的重声明只可能发生在某一个代码块中。如果与当前的变量重名的是外层代码块中
    的变量,那么就是另外一种含义了。
  3. 变量的重声明只有在使用短变量声明时才会发生,否则也无法通过编译。如果要在此处
    声明全新的变量,那么就应该使用包含关键字var的声明语句,但是这时就不能与同一个
    代码块中的任何变量有重名了 。
  4. 被“声明并赋值”的变量必须是多个,并且其中至少有一个是新的变量。这时我们才可
    以说对其中的旧变量进行了重声明。

这样来看,变量重声明其实算是一个语法糖(或者叫便利措施)。它允许我们在使用短变量声明时不用理会被赋值的多个变量中是否包含旧变量。可以想象,如果不这样会多写不少代码。

var err error
n, err := io.WriteString(os.Stdout, "Hello, everyone!\n")

我使用短变量声明对新变量n和旧变量err进行了“声明并赋值”,这时也是对后者的重声明。

到此这篇关于关于golang类型推断和变量重声明详解的文章就介绍到这了,更多相关golang类型推断和变量重声明内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Go语言学习之context包的用法详解

    Go语言学习之context包的用法详解

    日常Go开发中,Context包是用的最多的一个了,几乎所有函数的第一个参数都是ctx,那么我们为什么要传递Context呢,Context又有哪些用法,底层实现是如何呢?相信你也一定会有探索的欲望,那么就跟着本篇文章,一起来学习吧
    2022-10-10
  • 一文详解Go语言io包中的discard类型

    一文详解Go语言io包中的discard类型

    这篇文章主要介绍了Go语言io包中的discard类型示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-07-07
  • go判断文件夹是否存在并创建的实例

    go判断文件夹是否存在并创建的实例

    这篇文章主要介绍了go判断文件夹是否存在,并创建的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-12-12
  • 浅析Go语言中的方法集合与选择receiver类型

    浅析Go语言中的方法集合与选择receiver类型

    这篇文章主要为大家详细介绍了Go语言中的方法集合与选择receiver类型的相关知识,文中的示例代码讲解详细,对我们深入学习go语言有一定的帮助,需要的可以参考下
    2023-11-11
  • golang 格式化输入输出操作

    golang 格式化输入输出操作

    这篇文章主要介绍了golang 格式化输入输出操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-12-12
  • GoLang函数与面向接口编程全面分析讲解

    GoLang函数与面向接口编程全面分析讲解

    这篇文章主要介绍了GoLang函数与面向接口编程,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧
    2023-01-01
  • Go程序的init函数在什么时候执行

    Go程序的init函数在什么时候执行

    在Go语言中,init 函数是一个特殊的函数,它用于执行程序的初始化任务,本文主要介绍了Go程序的init函数在什么时候执行,感兴趣的可以了解一下
    2023-10-10
  • 使用Golang实现对网络数据包的捕获与分析

    使用Golang实现对网络数据包的捕获与分析

    在网络通信中,网络数据包是信息传递的基本单位,抓包是一种监控和分析网络流量的方法,用于获取网络数据包并对其进行分析,本文将介绍如何使用Golang实现抓包功能,包括网络数据包捕获和数据包分析,需要的朋友可以参考下
    2023-11-11
  • Go语言:打造优雅数据库单元测试的实战指南

    Go语言:打造优雅数据库单元测试的实战指南

    Go语言数据库单元测试入门:聚焦高效、可靠的数据库代码验证!想要确保您的Go应用数据层坚如磐石吗?本指南将手把手教您如何利用Go进行数据库单元测试,轻松揪出隐藏的bug,打造无懈可击的数据处理逻辑,一起来探索吧!
    2024-01-01
  • Go|使用Options模式和建造者模式创建对象实战

    Go|使用Options模式和建造者模式创建对象实战

    这篇文章主要介绍了Go使用Options模式和建造者模式创建对象实战详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-04-04

最新评论