程序的运行本质就是一系列状态的变化,比如:在游戏程序的运行过程中,一个角色的等级由0级升级到10级、金钱由10增长到了1000等。
所以程序的开发语言中必须有一种机制/语法能够控制计算机记录下事物状态,并且该状态是可以发生变化的,这就是变量。
变量是对“量”与“变”行为的抽象总结, “量”指的是记录下状态,“变”指的是记录的状态是可以发送变化的。状态是记录/存储到内存中的,又称之为数据,所以说每个变量都对应一块内存空间,而变量其实就像是一个容器。声明变量就是创造了一个容器(在内存空间中开辟了一块空间),为变量初始化或赋值就是在往容器里填充/改变内容。
分为两大类:var声明与简短声明
四种具体形式如下
| |
| var 变量名 类型 = 初始表达式 |
| |
| |
| var 变量名 类型 |
| |
| |
| var 变量名 = 初始表达式 |
| |
| |
| 变量名 := 初始表达式 |
举例
| var name string = "egon" |
| |
| var name string |
| |
| var name = "egon" |
| |
| name:="egon" |
前提:声明的一组变量中每个变量都必须被赋值!!!!!!
| |
| var a, b, c int = 10,20,30 |
| fmt.Println(a,b,c) |
| var x, y, z int |
| fmt.Println(x,y,z) |
| |
| |
| var x, y, z = true, 3.1, "egon" |
| |
| |
| var ( |
| m int = 3 |
| n string |
| ) |
| |
| |
| |
| |
| i, j := 0, 1 |
思考下述赋值是否正确,并说明原因
| |
| var a, b, c int = 30 |
| fmt.Println(a,b,c) |
| |
| |
| x, y := 3 |
| fmt.Println(x,y) |
| |
| |
| x:=1 |
| y:=2 |
| x,y:=111,222 |
| fmt.Println(x,y) |
| |
| |
| x:=1 |
| y:=2 |
| x,y,z:=111,222,333 |
| fmt.Println(x,y,z) |
| |
| |
| in, err := os.Open(infile) |
| out, err := os.Create(outfile) |
| |
| |
| f, err := os.Open(infile) |
| f, err := os.Create(outfile) |
| |
| 解决方法:第二个简短声明语句改为赋值语法,注意是赋值语法而不是声明语法 |
| f, err = os.Create(outfile) |
下划线_称之为匿名变量(anonymous variable)
,接收的值不占用命名空间、不会分配内存、且无法被使用,即它接收的值都相当于被废弃掉了
| func main() { |
| |
| _=1 |
| _=2 |
| _=3 |
| |
| |
| var _ = 1 |
| var _ = 2 |
| var _ = 3 |
| |
| |
| fmt.Println(_) |
| } |
综上,匿名变量通常用于多重赋值时忽略某个值,如下所示
| func main() { |
| |
| |
| var age,_=foo() |
| fmt.Println(age) |
| |
| var _,name=foo() |
| fmt.Println(name) |
| } |
| |
| func foo()(int,string) { |
| return 18,"egon" |
| } |
了解:在Lua
等编程语言里,匿名变量也被叫做哑元变量。
-
1、在函数内
| package main |
| |
| import "fmt" |
| var x int = 3 |
| func main() { |
| |
| |
| |
| fmt.Println(x) |
| var x int = 4 |
| } |
- (2)函数内声明之后就必须要用,否则无法通过编译,函数外则没有这一限制
注意:读取变量的值进行打印或运算才叫使用变量,声明与赋值不是引用变量。
-
2、匿名变量无需声明,且不能被使用,接收即废弃
-
3、同一作用域内不能出现重复的声明,匿名变量除外
-
4、var声明与简短声明
- (1)var可以用于任意位置,即用在函数外也行,但简短声明只能用于函数内部
- (2)事实上,声明语句var通常的用于”初始值无关紧要,变量稍后会被重新赋值“的场景,所以说,采用零值初始化是var语句的常态
- (3)请记住“:=”是一个变量声明语句,而“=‘是一个变量赋值操作;所以,千万不要混淆多个变量的声明和元组的多重赋值,后者是将右边各个的表达式值赋值给左边对应位置的各个变量:
| |
| i, j := 111, 222 |
| |
| |
| i, j = 333, 444 |
| i, j = j, i |
| |
| |
| _ := 666 |
引用变量/变量值的方式可以是
1、使用变量名
2、使用表达式,比如x[i]、x.f、*p
引入一个例子
左值与右值
| var x int = 100中的x,与y:=x中的x是不一样的 |
| |
| (1) var x int = 100中的x位于赋值符号的左边,称之为左值,代表的是赋值/写操作 |
| 会被编译器编译成一个地址,类似:0X3000,所以其左值代表的是内存地址, |
| |
| (2)、y:=x中的x位于赋值符号的右边,称之为右值,代表的是取值/读操作 |
| 会被编译器编译成一个根据地址取值操作,类似:(0X1000),所以右值代表的是根据地址读取内存空间中的内容。 |
| |
| !!!注意!!! |
| (0X1000)取到的内容,可能是一个值也可能是一个地址,无论是啥,都会将该内容拷贝一个副本来进行后续操作。这句话很重要,如果不理解也没啥关系,先死记硬背下来,你将会在指针那一小节得到详细答案 |
总结:无论采用何种方式使用变量
| 当变量的引入方式存在于赋值符号左边时,代表是对变量进行写操作 |
| 当变量的引入方式不在赋值符号左边时,,代表是对变量进行读操作 |
| fmt.Println(x) |
| z:=x+200 |