Go 编程 | 连载 02 - 变量与常量

262 阅读5分钟

一、Go 中的变量

Go 单个变量的定义

Go 是 静态强类型语言,但是 Go 语言在定义变量时可以自动识别变量的类型,当然也可以在定义变量时指定变量类型。

Go 中最基础的变量定义方式是通过 var 关键字来定义的。Go 中的基础数据类型有 int、float64、string 等。

// var + 变量名 + 变量类型
var i int

// 定义并初始化
var x float64 = 1.0

与 Java 等静态类型语言中不同的是,Go 中变量的类型是可以省略的,可以根据变量值自动判断类型。

// var + 变量名
var y = 10

当一个变量是全局变量时,应该使用 var 变量名 变量类型(可省略) 这种定义方式。

其实 Go 的变量定义方式还可以更加简化,那就是省略 var 关键字,使用 := 代替 = 来定义变量,这种定义方式只能用于定义 局部变量

// 使用 := 符号
z := "Go"

在定义变量的时候,以上三种定义方式都可以独立的定义变量,注意定义变量的时候,不要混用上面三种定义方式。

// 重复定义,编译不通过,编译器会有报错提示
var i int = 10
i := 10

Go 多个变量的定义

类似 Python,Go 也支持一次性定义多个变量,同样也有上述三种定义方式

var (
   a int
   b float64
   c string
)
a = 1
b = 2.0
c = "Go"

// 省略类型
var x, y, z = 0, 0, 0

// 省略 var 关键字和变量类型
e, d, f := 1, 2.0, "Go"

当变量的类型一致时就可以省略括号和变量类型,只在最后一个变量的后面指定类型就可以

var x, y, z int

Go 中的匿名变量

除了普通的变量外,Go 中还存在着一种匿名变量,由于 Go 中的变量一旦定义就必须使用,否则执行就会报错。

匿名变量与匿名函数的作用一致,就是针对一些只会使用一次且不会在别处使用的变量,使用匿名变量同时也可以避免 Go 运行时由于变量未使用而导致的报错。

Go 中使用 _ 来定义匿名变量, Go 中的函数可以定义多个返回值,所有会有一些返回值表示函数运行成功或者失败,如标准输出函数 fmt.Println() 就有两个返回值,一个是 int 类型,另一个是 error 类型。

image.png

可以把接收到的 error 类型的值定义为一个匿名变量

func main() {

   a := "Go"

   res, _ := fmt.Println(a)

   fmt.Println(string(res))
}

执行上述代码,输出结果如下:

Go

Go 中的全局变量

Go 中定义的全局变量时不能使用 := 来定义,前两种变量的定义方式都可以用于定义全局变量;且全局变量不使用,也不会报编译错误。

二、Go 中的常量

Go 常量的定义

Go 中常量的定义要使用 const 关键字,常量的类型可写可不写。常量定义之后如果未使用不会报错。

const URL string = "https://juejin.cn/"
const PI = 3.1415926

也可以一次定义多个常量

const (
   NAME    string  = "tony"
   BALANCE float64 = 0.0
   YEAR    int     = 2022
)

常量的类型可以省略

const (
   NAME    = "tony"
   BALANCE = 0.0
   YEAR    = 2022
)

在定义多个常量时,如果常量组不指定类型和初始化值,则常量的值和类型与上一行定义的常量的值与类型保持一致。

const (
   URL1 = "https://juejin.cn/"
   URL2
   URL3
   URL4
)

fmt.Println(URL1, URL2, URL3, URL4)

执行上述代码,输出结果如下:

https://juejin.cn/ https://juejin.cn/ https://juejin.cn/ https://juejin.cn/

Go 常量的 iota

iota 是 Go 语言中的常量计数器,iota 可以使常量的赋值、维护更加简单,iota 只能在常量组中赋值时使用。

以定义枚举值为例,当枚举值非常多的时候,某个中间的枚举值废弃,但是仍然想保持枚举值的连续性,或者新增加一个枚举常量使用被废弃的枚举值,这个过程维护起来比较麻烦,可以通过 iota 机制给枚举常量自动分配枚举值。

iota 是计数器表达式,iota 表达式的值遵循逐行加 1 的原则。

func main() {

   const (
      ALPHA = iota
      BRAVO
      CHARLIE
      DELTA
      FOXTROT
   )

   fmt.Println(ALPHA, BRAVO, CHARLIE, DELTA, FOXTROT)
}

执行上述代码,输出结果如下:

0 1 2 3 4

在定义多个常量时,如果常量组不指定类型和初始化值,则常量的值和类型与上一行定义的常量的值与类型保持一致,所以这些常量的值等于 iota 这个表达式,而 iota 初始值从 0 开始,表达式每调用一次都会 +1,最终输出结果为 0 1 2 3 4

iota 只能在常量组中使用,且每个常量组中的 iota 都是从 0 开始计数,不同常量组中的 iota 互不影响。

iota 是一个表达式,输出的结果为数值,iota 可以与其他整数或者浮点数进行运算

func main() {

   const (
      ALPHA = iota + 2
      BRAVO
      CHARLIE
      DELTA
      FOXTROT
   )

   fmt.Println(ALPHA, BRAVO, CHARLIE, DELTA, FOXTROT)
}

执行上述代码,输出结果如下:

2 3 4 5 6

iota 表达式的值每行加 1,同一行表达式的值是相同的,即是一行中有多个常量赋值了 iota,他们的值是相同的,同一行中 iota 表达式的值相同,不会加 1。

func main() {

   const (
      ALPHA          = iota
      BRAVO, CHARLIE = iota, iota
      DELTA          = iota
   )

   fmt.Println(ALPHA, BRAVO, CHARLIE, DELTA)
}

执行上述代码,输出结果如下:

0 1 1 2

iota 表达式的逐行加 1 操作与其他常量的赋值互相无影响。

func main() {

   const (
      ALPHA = iota
      BRAVO
      CHARLIE = "CHAR"
      DELTA   = iota
      FOXTROT = "FOX"
      GOLF    = iota
      HOTEL
   )

   fmt.Println(ALPHA, BRAVO, CHARLIE, DELTA, FOXTROT, GOLF, HOTEL)
}

执行上述代码,输出结果如下:

0 1 CHAR 3 FOX 5 6

如果在连续的 iota 常量组中插入其他常量的赋值,那么该位置的 iota 数值会被赋值的常量替代,上述 iota 表示的值 2 和 4 被字符串 "CHAR" 和 "FOX" 替代。

我正在参与掘金技术社区创作者签约计划招募活动,点击链接报名投稿