「这是我参与2022首次更文挑战的第1天,活动详情查看:2022首次更文挑战」。
变量
在数学概念中,变量(variable)表示没有固定值且可变的数。但是在计算机系统实现角度来看,变量实际上是一段或多短用来存储数据的内存。
Go作为一种静态类型编程语言,是有固定类型的变量。类型决定了变量的内存空间大小和存储格式。
定义
关键字var用于定义变量,和C不同的是,类型放在变量名后。运行时内存会确保变量自动初始化为二进制零值,避免出现不可预测行为。
var a int //自动初始化为0 var b = false //自动推断类型为boolean
支持一次定义多个变量
var a, b int //定义a,b两个相同类型变量 var c, d = 100,"hello" //定义两个不同类型变量
开发过程中,建议使用组的方式进行变量定义
var ( a, b int c, d = 100, "hello" )
简短模式
除了使用var来进行变量的定义,还可以使用更加简短的方法。
func main() { a := 100 b := "hello world" }
但是使用过程中要注意简短模式存在以下限制条件:
- 定义变量,同时显示初始化
- 不能提供数据类型
- 只能在函数内部使用
简短定义在函数多返回值,以及if/for/switch等语句中定义局部变量非常方便。但简短模式并不总是重新定义变量,也可能是赋值操作。
func main() { a := 100 println(&a, a) a, b := 300, "world" println(&a, a) println(b) }
运行结果:
0x14000096f60 100 0x14000096f60 300 world
对比两次a变量的地址,可以看出两个a属于同一个变量。退化复制的前提条件是:最少有一个新变量被定义,且必须是同一个作用域。
func main() { a := 100 println(&a, a) a := 300 //报错,no new variables on left side of := println(&a, a) }
func main() { a := 100 println(&a, a) { a, b := 300, "nihao" //a属于不同作用域,都是重新定义变量 println(&a, a, b) } } 输出: 0x14000096f60 100 0x14000096f58 300 nihao
多变量赋值
在进行多变量赋值操作时,首先要计算所有右值,然后再一次完成赋值操作。
func main() { a, b := 5, 8 a, b = b + 1, a + 4 println(a, b) } 输出: 9 9
未使用错误
``` var a int //全局变量没有问题 func main() {
var a int //a declared but not used } ```
编译器将未使用的局部变量当作错误!!!
命名
命名建议
对于变量、常量、函数、自定义类型等进行命名时,通常优先选用具有实际意义、易于理解、阅读的字母或单词组合。变量命名建议如下:
以字母或下划线开始,有多个字母、数字和下划线组合而成。
- 区分大小写
- 使用驼峰拼写格式
- 局部变量优先使用短名
- 不要使用保留关键字
- 不建议使用与预定义常量、类型、内置函数相同的名字
- 专有名词通常会全部大写
空标识符
和python类似,Go也有个名为“_”的特殊成员(blank identifier).通常作为忽略占位符使用。可作表达式左值,无法读取内容。
常量
常量表示运行时恒定不改变的值。通常是一些字面量。使用变量主要是通过易于阅读的标识符号来代替魔法值,使得在修改常量值时,无需修改代码。
const a, b int = 857, 0x77 const name = "小小土豆爱吃鱼" const c = '你' const ( key, value = 1, 3.1415 success = false )
可以在函数内部定义常量,常量未使用不会报错。不同作用域常量名字可以相同。
func main() { const a = 857 println(a) const b = 3.1415926 { const a = "nihao" println(a) } } 输出: 857 nihao
枚举
Go语言并不支持众多其他语言明确支持的 enum 关键字。但是go提供另一种方法来实现枚举,那就是const+iota。
const ( a = iota //0 b //1 c //2 )
如中断itoa自增,则必须显式恢复。且后续自增按行序递增。
const ( a = iota //0 b //1 c = 100 //100 d //100(与上一行常量右值表达式相同) e = iota //4(恢复itoa自增,计数包含c,d) f //5 )
在实际开发工作中,建议使用自定义类型实现用途明确的枚举类型。
import "fmt" type State int //iota初始化后会自动递增 const ( Running State = iota //value ---> 0 Stopped //value ---> 1 Rebooting //value ---> 2 Terminated //value ---> 3 ) func (this State) String() string { switch this { case Running: return "Running" case Stopped: return "Stopped" default: return "Unknow" } } func main() { state := Stopped fmt.Println("state", state) } //输出 state Stopped //没有重载String函数情况下会输出 state 1