Go语言之变量


变量是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语言中都是需要初始化的。
变量的命名规范一般遵循驼峰命名法:首个字母小写,每个独立的单词的首字母大写,例如: setNumbackTop(常量命名建议全部大写,遵循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)
}

init函数

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)
}

你可能感兴趣的:(Go语言学习之路,GoLang)