Go常量const
Go语言中的const整合了C语言中的宏定义常量,const只读变量枚举变量
- 绝大多数情况下,Go常量在声明时,并不显示的指定类型
- Go在处理不同类型的变量间的运算时不支持隐式的类型转换,必须进行显示的类型转换。
- Go的无类型常量,拥有字面量的特性。该特性使得无类型常量在参与变量赋值和计算过程中,无需显示的进行类型转换
无类型常量使得go在处理表达式混合数据类型运算时具有很高的灵活性。
Go中常量的定义和使用
定义格式:
const (
常量名 = 值
......
)
在const代码块中进行对常量的声明,一般使用时,多数使用无类型常量定义。
例如,定义两个无类型常量,在使用时会自动进行类型的隐式转换,很方便:
package main
import "fmt"
// 在const代码块中进行常量的声明定义
const (
a = 10
b = 33.3
)
func main() {
var number1 int = a
var number2 float32 = a + b // 转换成为 float32 数据类型
fmt.Println(number1, number2)// 10 43.3
fmt.Printf("%T\n%T\n",number1,number2)// int float32
}
无类型常量是Go语言推荐的最佳实践,它拥有和字面值一样的灵活性,可以直接用于更多的表达式而不需要显示的进行类型转换。
Go特性const,“隐式重复前一个表达式”
在Go的const语法中,提供了一个“隐式重复前一个表达式”的机制。
package main
import "fmt"
const(
blue = 1
yellow
green
blank
)
func main(){
fmt.Printf("%d\t%d\t%d\t%d\t",blue,yellow,green,blank)
\\ 1 1 1 1
}
可以很神奇的发现,在const定义的常量中,如果没有确切的赋值,则会隐式的重复前一个表达式的机制。如上面,我们将blue初始化为1,后续的常量初值并不进行初始化,则其余常量值都会变为1(隐式的重复前一个表达式的机制)。这个机制在iota实现枚举常量中十分常用。
iota 实现枚举常量
iota是Go提供的一个预定义标识符,它在const声明块中每个常量所处位置在块中的偏移,每一行的iota自身都是一个无类型常量,可以像无类型常量那样自动参与不同类型的求值过程,而无须对其进行显示的类型转换。
例如:
package main
import "fmt"
// 使用iota实现go语言中的枚举常量enum
const (
n1 = 1 << iota
n2
n3
n4 = iota
)
func main() {
fmt.Printf("%d\t%d\t%d\t%d\t", n1, n2, n3, n4)
// 1 2 4 3
}
分析一波上面的代码:
- 在
n1 = 1<<iota
时,n1=1,iota=0 - n2时,由于在const中定义,若未初始化常量值,则会隐式的重复前一个表达式,则
n2 =1<<iota
,此时n2=2,iota=1(偏移量为1) - n3时,与n2一致(隐式的重复前一个表达式),
n3=2<<iota
,n3=4,iota=2 n4=iota
,此时iota的偏移量为4,则n4=4
iota 使得 Go在定义枚举常量时十分灵活和方便:
iota预定义标识符可以更为灵活的形式为枚举常量赋值
Go的枚举常量不限定于整数值,也可以定义浮点型的枚举常量
iota使得维护枚举常量列表更为容易(对比一下传统的常量列表定义和使用iota的const常量定义)
// 不使用iota的传统枚举常量定义 const( n1 = 1 n2 = 2 n3 = 3 n4 = 4 ) // 使用iota的枚举常量定义 const( _ = iota n1 n2 n3 n4 )
当我们需要为常量列表中添加某一个常量时,如果使用第一种传统的方式定义,则需要手动的进行定义和赋值(同时你也需要观察旧的枚举列表,从而对新添加的常量进行赋值),而使用第二种iota时,则可以很灵活的自由添加。
使用有类型枚举常量保证类型安全。