变量
- 变量名让你能够把程序中准备使用的每一段数据都赋值给一个简短、易于记忆的名字。
变量声明及使用
变量的定义
|
|
- 显示声明变量:在声明变量时指定变量的类型。
- 隐式声明变量:在声明变量时并未指定变量的类型,而是在编译阶段编译器根据变量值自动判断类型。
- 整数类型(正数或负数,十进制、十六进制、八进制、二进制):编译器会全部识别为
int
类型,如:var a = 123
。 - 字符串:编译器识别为
string
类型,如:var b = "a1"
。 - 浮点数:编译器识别为
float64
类型,如:var c = -1.0
。 - 复数:编译器识别为
complecx128
类型,如:var d = 1i
。 - 字符类型:编译器识别为
rune
(int32) 类型,如:var e = 'a'
。 - 其他类型根据情况判断,如:
var f = map[string]int{}
这一定是map
,其他类似。
- 整数类型(正数或负数,十进制、十六进制、八进制、二进制):编译器会全部识别为
|
|
简单声明
- 简单申明使用
:=
,当声明一个变量时当前变量在当前作用域内未被声明过时。(只能用于函数内)
|
|
多变量赋值
|
|
|
|
- 总结,
:=
会在当前作用域寻找变量,如果找到则使用它,如果未找到则声明一个新变量。 - 注意,
:=
必须要求左边存在至少一个未定义的变量。:=
只能在函数内使用。
变量交换
|
|
标识符
- 由字母、数字、下划线(
_
)组成,其中首字符不能为数字,区分大小写(同一字母的大小写代表不同的标识)。 Go
语言规范:- 标识符:命名程序实体,如变量名和类型名。
- 标识符是一个或多个
Unicode
字母和数字的序列。 - 标识符中的一个字符必须是
Unicode
字母(下划线_
也被认为是字母)。 identifiter = letter {letter | unicode_digit}
letter = unicode_letter | _
:letter 包含字母(包括除英文字母以外的字母)和下划线。unicode_digit = 0 1 2 3 4 5 6 7 8 9
:数字(这里也包括除阿拉伯数字以外的数字)。
- 在
Go
语言中,命名标识符时,通常选择英文的52
个大小写字母以及数字0~9
和下划线来组合成合适的标识符。
|
|
关键字
Go
语言中关键字是保留字,不能作为变量标识符,关键字一共有25个。
Go 关键字
break
:用于跳出for
循环,跳出switch
和select
块。
switch
和select
都默认自带break
(如果写了break默认跳出当前块)。continue
:用于for
循环,表示结束本次循环继续下次循环。default
:用于switch
和select
结构的默认分支,当所有case
都不满足时执行default
分支。func
:用于定义函数或方法或函数类型变量。interface
:用于定义接口类型。select
:选择结构,主要用于chan
类型在,注意在select
中不能使用关键字fallthrough
。case
:用于select
和switch
关键字中,表示一个分支块。defer
:主要用于func
关键字定义的函数和方法体中,表示当前语句在函数退出时执行。go
:主要用于创建一个goroutine
放入P中等待被线程调用,这也是创建协程的关键。map
:用于定义字典类型。struct
:用于定义结构体类型。chan
:用于定义通道类型,chan
的主要作用是在各个goroutine
间通信的通道。else
:与if
关键字配合使用,当上面所有条件都不满足时默认执行else
分支的代码块。goto
:跳转语句,配合标签能任意跳转到指定代码处,多在函数内使用。package
:用于.go
文件的包声明,多用于.go
文件的第一行代码。switch
:选择分支结构,常与case
、default
、fallthrough
一起使用。const
:用于定义常量。fallthrough
:用于switch
的case
块中,表示继续运行下一个case
块代码而不检查是否满足条件。
if
:分支选择结构多与else
或else if
一起使用。range
:与for
关键字一起使用,从slice
、map
、string
、array
、chan
等中迭代元素。
range
会拷贝slice
、array
需要迭代的集合副本,以便于原集合区分。type
:多用于定义类型关键字。for
:用于开始一个循环。import
:导入其他包文件关键字。return
:用于函数或方法中,表示结束当前函数并返回给定值。
var
:用于定义变量的关键字。
注意事项
- 变量必须先定义才能使用,变量的类型和赋值的类型必须一致。
- 变量名不能冲突(同一个作用域内不能冲突)。
- 简短定义方式,只能在函数内被定义。
- 同一个作用域中,已存在同名的变量,则之后的声明初始化,则退化为赋值操作。
- 前提是,最少要有一个新的变量被定义,且在同一作用域。
- 变量定义了如不使用编译通不过。
|
|
作用域
- 在顶层声明的常量(如
const a int = 1
),类型(如type a int
),变量(如var a = 1
)函数的标识符(如func name() int
)的范围是包块。 - 导入包名称范围是包含导入声明的文件的文件块。
- 导入包名称范围是包含导入声明的文件的文件块。
- 在函数内声明的常量或变量标识符的范围从声明语句的末尾开始,到最内层包含块的末尾结束。
- 在函数内声明的类型标识符的范围从标识符开始,到最内层包含块的末尾结束。
- 块中声明的标识符可以在内部块中重新声明。
- 作用域就类似一棵树结构,而每个树枝相当于块,在树干定义的变量能被这个树干分成出的树枝或树枝的树枝使用,而在树枝中重复定义树干的变量则会屏蔽调树干定义的变量。
|
|
未使用的变量
- 未使用的全局变量编译不会报错。
- 函数内未使用定义的变量编译会报错,
import
导入的包,未使用编译会报错。
|
|
下划线
- _ :是特殊标识符,用来忽略结果。该变量是只写,并且是系统定义好的变量,可以随意使用不分作用域。
下划线在import中
- import:导入其他package包文件。
- 当前 _ 用于 import 中,仅仅是为了调用 init() 函数,所以无法通过包名来调用包中的其他函数和全局变量。
项目目录结构如下:
src目录
|
+--- main.go
|
+--- hello目录
|
+--- hello.go
|
|
|
|
- 其他示例
|
|
下划线当做变量使用
- _ :当做变量使用,表示丢弃,是只写变量,不能读取。
- 下划线用作判断切片下标是否越界时,
_ = a[3]
,有助于帮助编译器进行边界越界检查。
|
|
下划线在编译原理中
- 在编译原理中语法分析中,分析
const ()
关键字区分组时存在这样结构。
|
|
总结
- 下划线用在import中,仅仅是执行导入包的所有init()函数。
- 下划线在变量中,表示抛弃该值:
- 不占用命名空间,不会分配内存。
- 多次使用不存在重复声明问题。
- 很多时候
_
用于占位,表示忽略值。
- 我们可以把
_
当做是一个系统已经声明的全局只写变量,直接使用即可,不需要像_ := a
这种形式
参考
- 为什么指针被誉为 C 语言灵魂?,关于指针。