变量是Go语言中表示抽象值和存储计算结果的一种概念。变量的值通过变量名的访问,Go语言的变量命名规则与常量命名一样,都是由字母、数字、下划线组成,其中名称首个字符不能为数字。
变量声明的格式为:var identifier type
,也就是需要使用到关键字var,在Go语言中声明变量时将变量的类型放在变量的名称后面,这与其他语言不同。这样定义语法有多种原因,其中一种就是为了避免像C语言中出现有歧义的声明情况。
另外,这样的从左到右的语法声明,更符合人类语言习惯。就像这样:
//定义一个变量为int型
var a int
// 定义一个变量为bool型
var b bool
// 定义一个变量为string型
var str string
// 定义两个变量为int型
var a,b int
也可以与常量一样这样声明:
var (
a,b int
c bool
str string
)
// 同一类型的多个变量可以声明在同一行
var a,b,c int
// 多变量可以在同一行进行声明和赋值
var a,b,c int = 1,2,3
// 多变量可以在同一行进行赋值(这样的赋值只能在函数体内)
a,b = 5,7
如果想要交换两个变量的值,可以使用a,b = b,a
语句。
上面的声明方式都称为静态声明,除此之外,Go语言还有动态声明方式,该声明方式与常量声明一样,就像这样:
var a,b,c = "string",1,true
在这种动态声明中,变量可以拥有不同的类型,Go语言编译器会自动推断
变量的声明有两种写法,上面是一种,另一种就是:=
赋值运算符号代替,就像这样:
a := 1
// 等同于 var a = 1
此处也不指定变量类型也是因为Go语言编译器也会自动判断变量类型
Go语言官方推荐使用这种方式来声明变量,但是必须注意,这样的声明方式只能在函数体内,不可以用在全局变量声明与赋值。就像这样:
package main
import "fmt"
// 这种定义全局变量的写法是错误的,只能在
// a := 1
// 全局变量声明应该使用这种方式
var a := 1
// 一个全局变量只能声明一次,同一个代码块中不能再次声明
// a := 10
func main(){
b := 2 // 只能在函数体内使用这样的声明方式
a = 100 // 把10赋值给全局变量是没有语法问题的,注意这是赋值,不是声明
fmt.Println(a)
a:= "hello" // 函数体内部属于另一个代码块,可以再次声明变量a,这时可以改变变量类型
fmt.Println(a,b,c)
// 不能在变量声明之前调用变量
// fmt.Println(c)
// c := 4
}
// 全局变量声明不限定位置,在函数外部即可
var c = 0
使用 := 可以快速创建一个函数内部的变量,它包括初始化声明与赋值两大部分,使用这种方式声明变量需要注意以下几点:
当变量被声明但没有赋值时,它的值就是定义时指定类型的零值,例如int类型为0、float类型为0.0、bool类型为false、string类型为空字符串、指针为nil。如果变量被声明既没有指定类型,也没有指定值,那么系统就会默认它为int型的0值,所有变量在Go语言中都是需要初始化的。
变量的命名规范一般遵循驼峰命名法:首个字母小写,每个独立的单词的首字母大写,例如: setNum 和backTop(常量命名建议全部大写,遵循shell环境的习惯)。当然命名的规范并不是强制性的。
变量的类型也可以在运行时实现自动推断,就像这样:
package main
import (
"fmt"
"os"
)
var (
HOME = os.Getenv("HOME")
USER = os.Getenv("USER")
GOROOT = os.Getenv("GOROOT")
)
func main(){
fmt.Println(HOME,USER,GOROOT)
}
上面的例子展示了如何在运行时获取所在操作系统类型,它通过os包中的函数**os.Getenv()**来获取环境变量的值,并保存到定义的全局变量中。
全局变量是全局可用的,而局部变量只能在相应代码块内起作用,除此之外,局部变量还有一个特点就是,定义了就必须使用(而全局变量允许声明定义可以不使用)。如果定义了局部变量,但是在代码块内没有使用这个局部变量,那么编译也会出现错误,就像这样:
func main(){
a := 100
fmt.Printf("Hello World")
}
尝试编译这段代码系统将会抛出a declared and not used,这里的要求是使用,所以即使赋值也会出现编译错误,因为赋值属于声明定义的一部分,并不是使用变量,打印变量,将变量赋值给其他变量,或者加入某个运算中才叫被使用。
但是在使用强类型语言编程时,经常会出现在调用函数时,该函数会返回多个值,其中只有一个值才会被用到的情况。这个时候有一个办法可以解决这种问题,那就是使用空标识符,例如 _=a,这样就不会报变量没有使用的错了,这样的解决办法可以忽略一些多返回值的函数的部分返回值。
匿名函数的写法可以让代码看起来更加优雅,例如下面的函数GetClass()返回三个值,分别是stuNum、className、headTeacher:
package main
import (
"fmt"
)
// 定义获取班级信息的函数
func getClass()(stuNum int, className string, headTeacher string){
return 49,"一班","张三"
}
func main(){
stuName, _, _ := getClass() // 只需要获取班级人数stuNum
fmt.Println(stuNum)
}
Go语言中,除了可以在全局变量中初始化实体,也可以在init函数中初始化实体。init是一个特殊的函数,他会在包完成初始化后自动执行,执行优先级高于main函数,并且不能手动调用函数。每一个源文件有且只能有一个init函数,初始化过程中会根据包的依赖关系按顺序单线程执行。
可以在执行程序之前通过这个函数来对数据进行检验和修复,保证程序执行时状态正常。就像这样:
package main
import (
"fmt"
"math"
)
// Pi为圆周率
var Pi float64
func init(){
Pi = 4 * math.Atan(1) // 在init函数中计算Pi的值
}
func main(){
DPi := Pi * Pi
fmt.Println(Pi,DPi)
}