Skip to content

Latest commit

 

History

History

常量声明

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 

go 语言常量

go 使用 const 来声明常量,常量表达式的运算在编译期就可以完成了,并且 go 常量是类型安全的,编译器优化友好的元素。

常量中的数据类型只可以是布尔、数字 (整数、浮点和复数) 以及字符串型。

const(
  startOne = -2
  startTwo = 1.0
  startThree = 3.14
  isTrue = true
  hi = "hi"
)

go 推崇无类型常量,这主要是因为 go 不支持隐式的类型转化,只能显式转换,所以一旦常量给定类型,那么它跟变量之间或许就要将常量转化类型才能进行运算。

package main

import "fmt"

const (
	PI = 3.14
)

func main() {	
	var a float32 = PI
	var b float64 = PI
}

可以看到,如果是没有类型的常量,可以非常灵活的赋予 float32 或者 float64 都可以。

局部常量

在 Go 中,局部常量在编译期常量折叠 (compile-time constant folding) 时会被编译器处理成字面值,因此局部常量在编译时会被编译。

例如,下面的代码定义了一个局部常量 x,并使用它来初始化一个变量 y:

func main() {
    const x = 42
    var y = x * 2
    fmt.Println(y)
}

在编译时,x 将被处理成字面值 42,因此编译器将 y 初始化为 84,如下所示:

func main() {
    var y = 84
    fmt.Println(y)
}

可见,局部常量在编译期已经被折叠成了字面值,因此在运行时不会再进行计算了。

常量不可包含计算

在 Go 中,常量必须在编译时就可以确定其值。因此,常量的值必须是一个编译时的常量表达式,不能包含运行时的计算。

不过,常量表达式可以包含一些简单的运算,例如加、减、乘、除、取模等算术运算,以及位运算、逻辑运算等。例如:

const (
    x = 2 + 3            // 常量表达式,结果为 5
    y = (x * 2) % 10     // 常量表达式,结果为 0
    z = x == 5 || y == 0 // 常量表达式,结果为 true
)

常量表达式还可以使用一些内置函数,例如 lencapmakenew 等,以及可以在编译期计算的一些标准库函数,例如 math.Sinmath.Pi 等。

总之,常量必须在编译期就可以确定其值,因此不能包含运行时的计算,但可以包含一些简单的算术、位运算、逻辑运算等。

枚举常量 iota

go 语言提供隐式重复前一个非空表达式的机制

package main

import "fmt"

const (
	PI = 3.14
	a
	b
	c
	d
	e
	f
)

func main() {
	fmt.Println(PI, a, b, c, d, e, f)
}

这段代码将会全部输出 3.14

iota 是 go 语言的一个预定义标识符,它表示 const 声明块中,每一个常量所处位置的偏移量,它本身也是一个无类型的常量,它的初始值是 0,意思是说此处的 iota 跟第一行比偏移了 0 个位置

const(
  a = 1 << iota
  b
  c
  d
  e
  f
)

同一行的常量 iota 值是一样的,可以理解为偏移量相同

const(
  a,b = iota
  c,d
)

如果要让 iota 的初始值是 1,那么可以这么做

const(
  _ = iota
  a
  b
  c
  d
)

iota 只需要在一个 const 群中出现一次即可,出现多次跟出现一次的效果一样

const(
  a = iota
  b = iota
  c = iota
)
// 一样
const(
  a = iota
  b
  c
)

当 iota 群中出现异类该如何处理

const(
  a = iota
  b = 12
  c = iota
  d
  e
  f
  g
)

答案就是异类输出自己的,其它的常量不受影响,比如这里的输出就是 0 12 2 3 4 5 6,只要记住 iota 是偏移位置就可以理解为什么是这么输出的了。

如果不考虑常量的灵活性,极致追求安全性,那么也可以给 iota 常量加上类型

const(
  a int = iota
  b
  c
  d
)

这种就要求变量类型必须是 int 才能被这些枚举类型接纳,但是一般常量还是用无类型的较为常见。