变量
变量是几乎所有编程语言中最基本的组成元素。从根本上说,变量相当于是对一块数据存储空间的命名,程序可以通过定义一个变量来申请一块数据存储空间,之后可以通过引用变量名来使用这块内存空间。
Go 是静态语言,静态语言和动态语言相比变量差异很大
- 变量必须先定义后使用
- 变量必须有类型
- 类型定下来后不能改变
变量声明
Go 语言变量声明使用 var
关键字,变量声明语句不需要使用分号作为结束符
语法
var 变量名 变量类型
var v1 int
var v2 string
var v3 [10]int // 数组
var v4 []int // 数组切片
var v5 struct {
f int
}
var v6 *int // 指针
var v7 map[string]int // map,key为string类型,value为int类型
var v8 func(a int) int
Go 为避免重复写 var
关键字,提供批量声明变量的方式,,相同类型的变量可以放在一块定义。
语法
var (
变量名1 变量类型
变量名2 变量类型
变量名3,变量名4 变量类型
...
)
var (
v1 int
v2 string
v3,v4 bool
)
变量初始化
对于声明变量时需要进行初始化的场景,可以使用 var
关键字,也可以使用 :=
短变量声明的方式
语法
var 变量名 变量类型 = 默认值 // 方式一
var 变量名 = 默认值 // 方式二:编译器可自动推导出变量名的类型
变量名 := 默认值 // 方式三: 编译器可自动推导出变量名的类型
var v1 int = 10 // 方式一
var v2 = 10 // 方式二:编译器可自动推导出v2的类型
v3 := 10 // 方式三:编译器可自动推导出v3的类型
注意:
- 出现在
:=
左侧的变量不应该是已经被声明过的,否则会导致编译错误:=
只能在函数内部使用,函数外部必须使用var
关键字
变量赋值
在 Go 语法中,变量初始化和变量赋值是两个不同的概念。变量初始化时不赋初始值,编译器会根据变量的类型给出默认值。例如:整型和浮点型变量的默认值为0,字符串变量的默认值为空字符串, 布尔型变量默认为false, 切片、函数、指针变量的默认为nil
下面为声明一个变量之后的赋值过程
var v1 int
v1 = 10
Go 语言的变量赋值与多数语言一样,但 Go 支持多重赋值。
例如:交换变量 i 和 变量 j 的值
在不支持多重赋值的语言中,交换两个变量的值需要引入一个中间变量
t = i;i = j; j = t;
而在 Go 中,直接交换即可
j,i = i,j
多重赋值的特性在 Go 语言库的实现被使用的相当充分,特别是函数的多返回值。
匿名变量
Go 语言中,支持多值返回,在某种情况下,我们需要忽略某个值,但 Go 语言变量声明之后必须使用,如果要忽略某个值,可以使用匿名变量(anonymous variable)。匿名变量用下划线 _
表示
func foo() (int, string) {
return 10, "Q1mi"
}
func main() {
x, _ := foo()
_, y := foo()
fmt.Println("x=", x)
fmt.Println("y=", y)
}
匿名变量不占用命名空间,不会分配内存,所以匿名变量之间不存在重复声明。 (在Lua等编程语言里,匿名变量也被叫做哑元变量)
常量
在 Go 语言中,常量是指编译期间就已知且不可改变的值。常量可以是数值类型(包括整型、浮点型和复数类型)、布尔类型、字符串类型等。
字面常量
所谓字面常量(Iiteral),是指程序中硬编码的常量,如
-12
3.1425926 // 浮点类型的常量
3.2+12i // 复数类型的常量
true // 布尔类型的常量
"foo" // 字符串常量
Go 语言的字面常量更接近我们自然语言中的常量概念,它是无类型的。只要这个常量在相应类型的值域范围内,就可以作为该类型的常量。
常量定义
Go 语言中通过 const
关键字定义常量,常量尽量全部大写,若多个单词使用下划线形式定义。
// 单个常量声明
const PI float32 = 3.1415926
// 多个常量同时声明
const (
PI = 3.1415
E = 2.7182
GOOD_NAME = "小米"
)
const
同时声明多个常量时,如果忽略了值则表示和上面一行的值相同。例如
const (
n1 = 100
n2
n3
)
上面示例中,常量 n1、n2、n3
的值都是 100
常量定义的右值也可以是编译器运算的常量表达式,比如
const mask = 1 << 3
注意
- 常量类型只可以定义 bool、数值(整数、浮点数和复数)和字符串
- 不曾使用的常量,没有强制使用的要求
- 显示指定类型的时候,必须保证常量左右类型一致
- 如果定义常量时没有指定类型,那么它和字面常量一样,是无类型常量
预定义常量
Go 语言预定了这些常量:true、false 和 iota。
特殊常量:iota
iota,特殊常量,可以认为是一个可以被编译器修改的常量。iota
在iota
关键字出现时将被重置为0。const中每新增一行常量声明将使iota计数一次(iota可理解为const语句块中的行索引)。 使用iota能简化定义,在定义枚举时很有用。
const (
n1 = iota //0
n2 //1
n3 //2
n4 //3
)
几个常见的 iota 示例
使用 _
跳过某些值
const (
n1 = iota //0
n2 //1
_
n4 //3
)
iota
声明中间插队
const (
n1 = iota //0
n2 = 100 //100
n3 = iota //2
n4 //3
)
const n5 = iota //0
定义数量级 (这里的<<表示左移操作,1<<10表示将1的二进制表示向左移10位,也就是由1变成了10000000000,也就是十进制的1024。同理2<<2表示将2的二进制表示向左移2位,也就是由10变成了1000,也就是十进制的8。)
const (
_ = iota
KB = 1 << (10 * iota)
MB = 1 << (10 * iota)
GB = 1 << (10 * iota)
TB = 1 << (10 * iota)
PB = 1 << (10 * iota)
)
多个 iota
定义在一行
const (
a, b = iota + 1, iota + 2 //1,2
c, d //2,3
e, f //3,4
)
注意
- 如果中断了iota,那么必须显式的恢复,后续会自动递增
- 自增类型默认是int类型
- iota能简化const类型的定义
- 每次出现const的时候,iota初始化为0
枚举
枚举指一系列相关的常量。Go 语言中通常使用 const
后面跟一对圆括号的方式定义一组常量用于定义枚举值。Go 语言并不支持众多其他语言明确支持的 enum
关键字
下面是一个常规的枚举表示法,其中定义了一系列整型常量:
const (
Sunday = iota
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
numberOfDays // 这个常量没有导出,在包外不可用
)
同 Go 语言的其他符号(symbol)一样,以大写字母开头的常量在包外可见。