什么是变量

变量(variable) 一词来源于数学,是计算机中存储计算结果或表示值得抽象概念,我们可以通过变量名访问变量的值。

 

Go 语言是静态类型语言,在静态类型语言中变量必须指定一个类型,例如:整型,布尔型,字符串,数组,指针等。Go语言的每一个变量都有自己的类型,变量必须经过声明才可以使用。可以在声明变量时指定变量的类型,也可以让编译器自动推断变量类型。

 

标准格式

Go 语言变量声明的标准格式为

var 变量名 变量类型

var 是声明变量的关键字,中间用空格隔开,和C语言不同的是,Go语言的变量名在前,变量类型在后,行尾无须分号,var关键字通常被使用在函数的外部和内部,在函数外部作为全局变量使用,在函数内部作为局部变量使用

 

例如:我们声明一个age整型变量,用来表示人的年龄

var age int

var 是声明变量的关键字,age是变量名,int是变量的类型

 

基本类型

Go 语言的基本类型有:

• bool // 布尔类型
• string // 字符串
• int,int8,int16,int32,int64
• uint,uint8,uint16,uint32,uint64,uintptr
• byte // uint8的别名
• rune // int32的别名 表示一个 Unicode 码
• float32,float64 // 浮点型
• complex64,complex128 // 复数

 

有过编程开发经验的同学应该很熟悉,其中的变量类型和其它语言的变量类型基本一样。在 Go 语言中,一个变量被声明后,系统会自动赋予它该类型的零值: bool是布尔类型为false,int是整型为0,float浮点型是0.0,string字符串类型为空字符串,指针类型为nil等。

 

没有编程开发经验的同学可能会有疑问了?既然有int这个类型了,为什么还有int8,int16,int32,int64这些类型,这些类型之间有什么区别和联系?int表示整型,每声明一个变量都是需要占用计算机内存的,在32位机器上,占用4个字节,在计算机中一个字节占8位,共32位,在64位机器上占用8个字节,占用64位,int8表示占用一个字节8位,int16表示占用2个字节,int32表示占用4个字节,int64表示占用8个字节,其它变量类型可依次类推

 

命名规则

和其它语言类似,Go 语言的变量命名遵循以下规则:

1,变量名必须以字母或下划线大头,名字中间由字母,数字和下划线"_"组成,下划线"_"表示匿名变量

2,变量名不能是标识符和关键字

3,变量的名字区分大小写,例如: age和Age是不同的变量

4,变量的命名一般采用驼峰命名法,即首个单词小写,每个新单词的首字母大写,例如: userName,fileName等等。

 

批量声明

每声明一个变量就写一个var关键字会比较繁琐,Go 语言支持批量声明

var (
    a int
    b bool
    c string
)

 

类型推导

有时候我们使用批量声明也会觉得比较麻烦,能不能在简化一点,这时候我们可以把变量的类型省略,在编译阶段编译器会自动推导变量的类型来完成初始化

var age = 100  
var (
   name = "zhang san"
   host = "127.0.0.1"
   port = 8080
)

 

简短格式

如果你觉得使用var关键字批量声明还是比较麻烦,还有没有更简单的声明格式,当然除了使用var关键字声明变量,还可以使用更加简短的格式声明变量,省略var关键字和变量的类型来声明变量

name := "zhang san"
host := "127.0.0.1"
port := 8080

直接使用:=的形式来声明变量和初始化,这样声明是比较简单方便,不过也有它的局限性,这种声明方式有以下限制:

  • 定义变量,同时显示初始化
  • 不能提供数据类型,由编译器自动推导
  • 只能用在函数内部,作为局部变量使用

 

匿名变量

还有一种变量的声明方式,或许你在看开源代码的时候会发现,有一些变量直接使用下划线"_",这样做有什么意义吗?

 

这就是我们要说的匿名变量,在使用多重赋值时,如果想要忽略某个值,就可以使用匿名变量,这在获取方法返回多个结果的时候经常被使用。匿名变量多用于占位,表示忽略值,不占用命名空间,不会分配内存,所以匿名变量不存在重复声明。

 

例如下面摘自Go源码中一个写文件的方法,在第6行使用了一个下划线"_"来接收方法返回的结果

func WriteFile(filename string, data []byte, perm os.FileMode) error {
   f, err := os.OpenFile(filename, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm)
   if err != nil {
      return err
   }
   _, err = f.Write(data)
   if err1 := f.Close(); err == nil {
      err = err1
   }
   return err
}