教程 > Go 教程 > Go 基础 阅读:277

Go 变量详解

本章节我们介绍 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 就被称为 动态类型声明

查看笔记

扫码一下
查看教程更方便