Go 变量详解
本章节我们介绍 Go 变量。对于变量,可以认为就是给内存中一块区域指定一个名称。我们可以通过这个名称直接访问这块儿内存。既然是变量,意思也就是说这块儿内存里的内容,也就是变量值,是可以改变的。我们可以通过使用这个变量名,通过某些方式对这块儿内存中的值进行修改。这也是区分于变量和常量的关键点。(关于常量,我们在后面章节中介绍)
通过上图,我们基本上可以了解,Go语言中的变量基本上有三个元素构成:
- 变量名
- 内存
- 变量的数据类型,也就是这块儿内存只能存放哪种类型的数据
变量名也应该是需要在内存中存储的,不过对于变量名怎么映射到内存,并且变量名又是如何进行访问的,这些都有底层来自动实现。不同的编程语言都有自己的内存模型,这里我们只关心用户层面变量的访问。
上面变量的三要素反应在Go语言中,其对应声明一个变量的语法如下
var name type
其中
- var 关键字用来告诉内核,用户在声明一个变量,要在内存中分配一块儿内存。
- name 就是这块儿内存的名字,也就是变量名。我们可以随便起,但是要遵循一定的规则,这里我们后面会讲到。
- type 表示的就是数据类型,也就是告诉内核,申请一块儿内存,这块儿内存里只能放我指定的类型的数据。例如,指定 string类型,则该内存块儿只能放字符串类型的数据。
变量命名规则
Go 语言变量命名规则和其他编程语言是相同的。 都是由 数字、字母和下划线组成。并且只能以字母和下划线开头,不能使用 数字开头
Go语言是区分大小写的,因此变量 varName 和 varname 是两个不同的变量。
变量定义
在上面我们了解到,声明一个变量需要由三个元素。其中 var 是一个关键字,用来声明一个变量的。type 是Go语言支持的基本数据类型,也可以是我们自己定义的数据类型。
下面我们定义几个变量
var i int
var j int
var str string
var b byte
上面的代码将会定义四个变量。然而我们却可以对上面的代码进行优化。对于同一数据类型的变量,我们可以使用一个 var 来声明,变量名称之间使用 逗号隔开,如下所示
var i, j int
var str string
var b byte
因为上面的 i 和 j 的数据类型相同,所以可以在一行进行声明。
警告
:不同类型的变量千万不能在一行进行声明,否则会报错。
变量可以在它们的声明中初始化(分配一个初始值)。变量的类型由编译器根据传递给它的值自动判断。例如
var i = 10
这样我们就声明了一个整型的变量i,并且对其进行了初始化,赋值10。
注意,这里就没有必要再在声明的时候指定变量的类型了,以下代码是无意义的
var i int = 10
而且有时候如果我们指定了变量的类型,但是在初始化赋值的时候类型给错了,那将会编译时就报错的。
var i string = 10
如果强制执行,则会报如下错误
./first.go:3:5: cannot use 10 (type int) as type string in assignment
因此我们在给变量初始化的时候,就不要再去指定变量的类型了。
有意思的是,如果我们不在变量声明的时候指定类型,而是直接初始化赋值的话,是可以不同数据类型在一行进行初始化定义的。如下代码所示
var i, j, str = 18, 36, "jiyik"
这就是所谓的混合变量声明
混合变量声明
可以使用类型推断一次性声明不同类型的变量。
package main
import "fmt"
func main() {
var i, j, str = 18, 36, "jiyik"
fmt.Println(i)
fmt.Println(j)
fmt.Println(str)
fmt.Printf("i is of type %T\n", i)
fmt.Printf("j is of type %T\n", j)
fmt.Printf("str is of type %T\n", str)
}
运行结果如下
18
36
jiyik
i is of type int
j is of type int
str is of type string
动态类型声明
动态类型变量声明要求编译器根据传递给它的值来解释变量的类型。这和上面介绍的省略数据类型还不太一样,这里不但可以省略变量类型,还可以省略关键字 var
。 使用 :=
运算符对变量进行初始化。我们看下面的例子
package main
import "fmt"
func main() {
var x float64 = 20.0
y := 42
fmt.Println(x)
fmt.Println(y)
fmt.Printf("x is of type %T\n", x)
fmt.Printf("y is of type %T\n", y)
}
代码执行结果如下
20
42
x is of type float64
y is of type int
上例中的 y:=42
就被称为 动态类型声明