Skip to main content

变量与常量

NANAbout 6 minGO

概念

变量常量是数据在内存中的抽象, 它们是内存地址的别名,用来方便我们操作内存中的数据。

比如我们有一组运算 $X = A + B, A = 1,B = 2 $ 需要完成,在计算机中我们需要

  1. 将 1 存储到内存中,假设存储在地址 0X0001,并为这个内存地址取一个别名 A
  2. 将 2 存储到内存中,假设存储在地址 0X0002,并为这个内存地址取一个别名 B
  3. 然后将 A 与 2 相加,得到结果 3, 在CUP中实际上就是:内存地址 0X0001 与 0X0002 所存放的数相加
  4. 把结果 3 存储到内存中,假设存储在地址 0X0003,并为这个内存地址取一个别名 X

在内存中的表现形式:

别名内存地址
A0X00011
B0X00022
X0X00033

有时这里的变量名也叫做标识符,及标识内存地址的符号,目的是为了方便我们在编程时对内存中的数据的进行存取

变量

可变的数据,当我们不确定一个数据的值是否是不变的时候,我们通常用变量来定义这个值

声明

在 Golang 中,我们使用 var 关键字来声明一个变量,语法如下:

/**
关键字 变量标识符 类型 赋值符号 值
var     x      int    =     1
*/ 
var x int = 1

在声明变量时可以不初始化,可以在变量声明之后进行再进行赋予值

  var x int // 这里会现在内存上开辟一块 int 类型的内存空间,并为这个内存地址取一个别名 x
  ......
  /**
  我们可以在需要为x赋值的时候,再进行赋值
  */ 
  x = 1 // 将数值 1 存储到内存中 x 标注的(内存地址指向的)空间中

在Golang中声明的变量必须使用,不使用会让程序报错,如果不想使用这个变量,可以使用 _ 来代替变量名

  var _ int = 1

在 Golang 中,常量不可以在同一作用域下重复声明

var x = 1
var x = 2 // 这里会报错,因为 x 已经声明过了
var x = 1 
func main() {
  var x = 2 // 这里不会报错,因为这里 x 在 main 函数中是重新声明的, 它们不在一个作用于内
}

在 Golang 中,我们可以同时声明多个变量,语法如下:

  // 批量声明法,可以单独指定每一个变量的类型
  var (
    a int = 1
    b int = 2
  )

  // 单一声明法(多重声明法),只能批量声明同类型的变量
  var x, y int = 1, 2 
  /**
  这里的语法可以理解为
  关键字 (变量标识符, 变量标识符) 类型 赋值符号 (值, 值)
  var      x, y               int   =      1,2
  简单的说就是int定义了()中的所有变量的类型

  var x int, y int = 1, 2 // 如果这样写会报语法错误
  */

在声明变量时,如果初始化了值,可以省略类型,Golang 会根据初始化的值自动推断变量的类型

  var x = 1 // 这里会自动推断 x 的类型为 int

在函数内部,可以使用 := 来声明并初始化变量,这种声明方式叫做简短声明,它只能在函数内部使用

  x := 1 
  /**
    它的本质是先使用 var 声明变量,然后使用 := 进行赋值
    var x int
    x = 1
  */

  // 它也可以用于同时声明多个变量
  x, y := 1, 2

在 Golang 中,我们可以使用 _ 来表示匿名变量,它表示忽略这个值,不进行存储,这个在我们获取函数的返回时非常有用

  _, b := 1, 2 // 这里会忽略 1,只存储 2 到 b 中

常量

恒定不变的数据,当我们确定一个数据的值是不变的时候,我们通常用用常量来定义这个值,它用来替代值的重复使用,且限制其的改变,它在编译时确定,在运行时不能改变

声明

在 Golang 中,我们使用 const 关键字来声明一个常量,语法如下:

/**
关键字 变量标识符    类型    赋值符号   值
const     PI    float32     =     3.14
*/ 
  const PI float32 = 3.14 // 常量在声明时必须初始化值

在 Golang 中,常量的值必须是编译期可确定的,也就是说,常量的值必须在编译时就确定,不能在运行时确定

  const TIME_NOW = time.Now() // 这里会报错,因为 time.Now() 是在运行时确定的

  func num() int {
    return 1
  }
  const A = num() // 这里也会报错

在 Golang 中,常量不可以在同一作用域下重复声明

const PI float32 = 3.14
const PI float32 = 3.14 // 这里会报错,因为 x 已经声明过了
const PI float32 = 3.14
func main() {
  const PI float32 = 3.14 // 这里不会报错,因为这里 x 在 main 函数中是重新声明的, 它们不在一个作用于内
}

在 Golang 中,我们也可以同时声明多个常量,语法如下:

  // 单一声明法(多重声明法),只能批量声明同类型的常量
  const X, Y int = 1, 2 
  /**
  这里的语法可以理解为
  关键字 (变量标识符, 变量标识符) 类型 赋值符号 (值, 值)
  const      x, y               int   =      1,2
  简单的说就是int定义了()中的所有变量的类型

  const x int, y int = 1, 2 // 如果这样写会报语法错误
  */

在使用批量声明法时,第一个常量必须初始化,后面的常量在编译时自动采用最后一个常量的类型和值

  const (
    A int = 1
    B // 1
    C // 1
  )

常量也可以自动进行类型推断

  const PI = 3.14 // 这里会自动推断 x 的类型

iota

iota可以在Go程序编译时修改常量的值,默认起始值为0
每创建常量一个,iota迭代次数就加1

  const (
    A = iota // iota = 0
    B       //  B = iota = 1
    C       //  C = iota = 2
  ) 

可以理解为在使用const关键字的时候,Golang就会自动创建一个iota迭代器, 并初始化值,默认为0,在接下来的过程中,每创建一个常量,iota的值就会自增1

  const ( // 初始化 iota = 0
    A = 0 // A = 0, iota++      执行完后(iota = 1)
    B   // B = A = 0, iota++    执行完后(iota = 2)
    C = iota // C = iota = 2, iota++  执行完后(iota = 3)
    D   // D = C = iota = 3, iota++  执行完后(iota = 4)
    E = iota + iota // E = iota + iota = 4 + 4 = 8, iota++  执行完后(iota = 5)

    F   // F = 10, iota++  执行完后(iota = 6)
    // 注意这里并不是将E的值直接赋值给F,换句话说并不是 F = E(值) = 10, 而是F = W = iota + iota = 5 + 5 = 10
  )