[Go 入门] 第二章 变量
Go 入门系列参考于互联网资料与 人民邮电出版社 《Go 语言入门经典》 与 《Effective Go》,编写目的在于学习交流,如有侵权,请联系删除
变量是计算机程序不可或缺的部分, 本文内容:
变量是什么
变量就是值的引用,是实现程序逻辑的基石之一
1 |
|
关于上面的解读应该为
- 使用关键字 var 声明一个变量
- 这个变量名为 s
- 这个变量的类型为 string
- 赋值运算符 = 表示将它右边的值赋给变量
- 将字符串的字面量 “Hello world!” 赋值给变量 s
声明变量后再给它赋值
1 |
|
快捷声明变量
Go 支持多种快捷变量声明方式,可在一行内声明多个类型相同的变量并给它们赋值
快捷变量声明
1 |
|
以快捷方式声明不同类型的变量
1 |
|
变量声明后,就不能再次声明它,但是可以重新给它赋值
理解变量和零值
在 Go 语言中,声明变量时如果没有给它指定值,则变量将为默认值,这种默认值将被称为 零值。变量的默认值取决于其类型
1 |
|
运行上面的代码,将会看到 0 0 false ""
使用变量时,要知道 Go 的这种决策十分的重要。在 Go 语言中要检查变量是否为已经赋值不能检查它是否为 nil
,而必须检查它的默认值,其次 Go 不允许将变量值初始化为 nil
值,因为这将会导致编译阶段错误
编写简短变量声明
1 |
|
解读如下
- 声明一个名为
s
的变量。这里没有指定关键字var
和类型 - 简短变量赋值语句 := 声明使用的是简短的变量声明,这意味着不需要使用关键字变量
var
,也不用指定变量的类型 - 将字符串 “Hello world!” 赋值给
s
使用简短声明时,编译器会推断变量的类型,因此无需显式的指定变量的类型,注意,只能在函数中使用简短的变量声明
变量声明方式
下面是 Go 所有的变量声明方式:1
2
3
4
5var s string = "Hello world!"
var s = "Hello world!"
var t string
t = "Hello world!"
u := "Hello world!"
Go 对使用哪种方式有一定的限制 —— 不能在函数外面使用简短的变量声明,在遵守这条规则的前提下,如何声明都可以
在同一行内声明变量并给它赋值时,Go 在标准库中约定如下:在函数内使用简短变量声明,在函数外省略类型。
理解变量的作用域
作用域指的是变量在什么地方可以用,而不是变量实在什么地方声明的。 Go 语言的使用基于块的词法作用域。在 Go 语言中,块是位于一对大括号内的一系列声明和语句。但可以是空的
- Go 语言中,一对大括号
{}
表示一个块 - 对于在大括号
{}
内声明的变量,可以在相应块的任何地方访问 - 大括号内的大括号定义了一个新块 —— 内部块
- 在内部块中,可以访问外部块中声明的变量
- 在外部块中,无法访问内部块中声明的变量
- 代码的缩进程度反应了块作用域的层级,在每个块中,代码都被缩进
- 在内部块中,可以引用外部块中声明的变量
使用指针
指针是另一个变量相关且必须掌握的要素,在声明变量时,将计算机内存中给它分配一个位置,以便能够储存、修改、获取变量的值。要获取变量在计算机内存中的地址,可以在变量前加上 &
字符
1 |
|
运行后,会得到一个内存地址 如 0xabcdef0000
将变量作为值传递
1 |
|
输出结果:1
20xc000070090
0xc000070098
将变量传递给函数时,会分配新内存并将变量的值复制到其中。这样将会有两个变量实例,它们将位于不同的内存单元中。一般而言,这不可取,因为这将占用更多的内存,同时,由于存在变量的多个副本,很容易引入 Bug
将变量作为指针传递
1 |
|
输出结果:1
20xc00000a0d8
0xc00000a0d8
改动说明:
- 将传递给 showMemAddress 的值从
i
改成了&i
,&
意味着引用的是变量i
的值所在的内存地址 - 将函数 showMemAddress 的第一个参数类型从
int
改成了*int
,加上星号意味着参数的类型为指向整数的指针,而不是整数 - 函数中打印变量时,不需要使用
&
因为它本来就是指针
如果需要获取指针的值,那么在其前面加上 *
1
2
3
4func showMemAddress(i *int) {
fmt.Println(*i)
return
}
声明常量
常量指的是整个程序生命周期内都不变的值,常量初始后,可以引用它,但是不能修改它
1 |
|
问题列表
不声明变量的类型是不是很危险?编译器在定义变量时会不会出现错误呢?
对于未显式声明的类型的变量,Go 编译器很善于动态地推断其类型。如果编译器推断不出来(可能性很小)会提示的