变量
编译器采用栈逃逸技术自动为变量分配空间,可能在栈上,也可能在堆上
标准声明
var 变量名 变量类型
var studentName string
变量声明可以写在函数外,但是全局变量不能和函数体内的局部变量重名,并且声明的变量必须使用(全局变量除外),变量声明采用小驼峰命名
批量声明
var (
name strig
age int
)
短变量声明
只能写在函数内部
name := "messi"
匿名变量
匿名变量用_表示,匿名变量不会被分配内存,也不占用命名空间,例如
package main
import (
"fmt"
)
func foo()(string, int) {
return "name", 1
}
func main() {
name, _ := foo()
fmt.Print(name)
}
变量赋值
单个变量初始化
var name string
name = "梅西"
或者
var name string = "messi"
多个变量初始化
var name, age = "messi", 15
这时候省略变量类型,编译器会根据赋值号右边的类型进行推导
或者是这样写
var score,age int
score, age = 10, 20
但是下面的写法是错的,因为name和age不是同一类型
var name, age
name, age = "messi", 15
多值赋值语义
- 对左侧操作数中的表达式,索引值进行计算和确定,首先确定左侧的操作数的地址,然后对右侧的赋值表达式进行计算,如果发现右侧的表达式计算引用了左侧的变量,将创建临时变量进行值拷贝,最后完成计算
- 按从左到右的顺序依此赋值
package main
import "fmt"
func main() {
x := []int{1, 2, 3}
i := 0
i, x[i] = 1, 2 //先确定左侧的索引,及x[i]中的i为0,然后进行修改
fmt.Println(i, x)
x = []int{1, 2, 3}
i = 0
x[i], i = 2, 1 //先确定左侧的索引,及x[i]中的i为0,然后进行修改
fmt.Println(i, x)
x = []int{1, 2, 3}
i = 0
x[i], i = 2, x[i] //由于右侧引用了左侧的变量,则创建临时变量进行值拷贝,最后完成计算
fmt.Println(i, x)
x[0], x[0] = 1, 2 //按照从左到右的顺序进行
fmt.Println(x[0])
1 [2 2 3]
1 [2 2 3]
1 [2 2 3]
2
}
常量
把变量声明中的var换成const即可,const同时声明多个变量时,如果省略了值则表示与上一行相同
常量存储在程序的只读数据段里
// 这种写法报错的原因是,不知道age的值
const (
age int
score = 1
)
iota
iota
是常量计数器,只能在常量表达式中使用,在const关键字出现的时候被置0,const中每新增一行常量声明就会让iota
计数一次,可以理解为是const语句块中的 行索引
常见示例
示例1
//b因为省略了值,所以和上面的a一样,都为iota,所以b为1
const (
a = iota //0
b //1
c //2
)
示例2
const (
a = iota
b //1
_ //2
c //3
)
示例3
const (
a = iota //0
b = 100
c //2
d //3
)
示例4
const (
a, b = iota + 1, iota + 2
c, d = iota + 1, iota + 2
// a = 1, b = 2, c = 2, d = 3
)