Golang编程之变量篇

我是研究僧i 提交于 2019-12-25 04:22:07

1、变量的简介

变量是大多数编程语言中最基本的组成元素。从本质上说,变量相当于是对一块或者多块数据存储空间的命名,程序可以通过定义一个变量来申请一块或者多块数据存储空间,之后可以通过引用变量名来使用这些存储空间。作为静态类型语言,Go语言变量总是有固定的数据类型,类型决定了变量内存的长度和存储格式。

2、变量的定义

关键字var用于定义变量,和C语言不同,类型被放在变量名后。

变量定义的一般语法如下:

var 变量名字 类型 = 初始化表达式

其中“类型”或“初始化表达式”两个部分可以省略其中的一个。如果省略的是“类型”,那么编译器将根据初始化表达式来推导变量的类型信息;如果“表达式”被省略,那么将用零值(数值类型变量对应的零值是0,布尔类型变量对应的零值是false,字符串类型对应的零值是空字符串,接口或引用类型变量对应的零值是nil)初始化该变量。零值初始化机制可以确保每个声明的变量总是有一个良好定义的值,因此在Go语言中不存在未初始化的变量。

在一个语句中同时定义一组变量,或用一组初始化表达式定义并初始化一组变量:

var i, j, k int // int, int, int
var b, f, s = true, 2.3, "four" // bool, float64, string

一组变量也可以通过调用一个函数,由函数返回的多个返回值初始化:

var ret, err = os.Open(name) // os.Open returns a file and an error

在函数内部,有一种称为简短变量声明语句的形式可用于声明和初始化局部变量。它以“变量名字 := 初始化表达式”形式声明变量,变量的类型根据初始化表达式来自动推导。

简短变量定义的语法如下:

变量名字 := 初始化表达式

简短变量定义和初始化一组变量(这种同时定义多个变量的方式应该限制在可以提高代码可读性的地方使用,比如for语句的循环的初始化语句部分):

i, j := 0, 1

因为简洁和灵活的特点,简短变量声明被广泛用于大部分的局部变量的声明和初始化。var形式的声明语句往往是用于需要显式指定变量类型地方,或者因为变量稍后会被重新赋值而初始值无关紧要的地方。

3、变量的初始化

对于定义变量时需要进行初始化的场景,var关键字可以保留,但不再是必要的元素,如下所示:

var v1 int = 10 // 正确的使用方式1
var v2 = 10 // 正确的使用方式2,编译器可以自动推导出v2的类型
v3 := 10 // 正确的使用方式3,编译器可以自动推导出v3的类型

以上三种用法的效果是完全一样的。与第一种用法相比,第三种用法需要输入的字符数大大减少。这里Go语言也引入了另一个C和C++中没有的符号(冒号和等号的组合:=),用于明确表达同时进行变量定义和初始化的工作。指定类型已不再是必需的,Go编译器可以从初始化表达式的右值推导出该变量应该定义为哪种类型,这让Go语言看起来有点像动态类型语言,尽管Go语言实际上是不折不扣的强类型语言(静态类型语言)。
当然,出现在:=左侧的变量不应该是已经被声明过的,否则会导致编译错误,比如下面这个写法:

var i int
i := 2

会导致类似如下的编译错误:

no new variables on left side of :=

4、变量的赋值

在Go语法中,变量初始化和变量赋值是两个不同的概念。下面为定义一个变量之后的赋值过程:

var v int
v = 10

Go语言的变量赋值与多数语言一致,但Go语言中提供了多重赋值功能,比如下面这个交换i和j变量的语句:

i, j = j, i

在不支持多重赋值的语言中,交互两个变量的内容需要引入一个中间变量:

t = i; i = j; j = t;
多重赋值的特性在Go语言库的实现中也被使用得相当充分,在介绍函数的多重返回值时,将对其进行更加深入的介绍。总而言之,多重赋值功能让Go语言可以非常明显地减少代码行数。

5、匿名变量

我们在使用传统的强类型语言编程时,经常会出现这种情况,即在调用函数时为了获取一个值,却因为该函数返回多个值而不得不定义一堆没用的变量。在Go中这种情况可以通过结合使用多重返回和匿名变量来避免这种丑陋的写法,让代码看起来更加优雅。
假设GetName()函数的定义如下,它返回3个值,分别为firstName、lastName和nickName:

func GetName() (firstName, lastName, nickName string) {
     return "May", "Chan", "Chibi Maruko"
}

若只想获得nickName,则函数调用语句可以用如下方式编写:

_,_,nickName := GetName()
这种用法可以让代码非常清晰,基本上屏蔽掉了可能混淆代码阅读者视线的内容,从而大幅降低沟通的复杂度和代码维护的难度。
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!