常量和Java中的意思类似,就是被定义后,在程序运行时,不会被修改的量。
Java中定义常量使用final 关键字,Scala中定义常量使用 val ,那么在Go语言中定义常量使用的是const.
常量中的数据类型只可以是布尔型、数字型(整数型、浮点型和复数)和字符串。
常量的定义:
const identifier [type] = value
定义常量的时候类型可以省略,例如:
const str = "abcde"
因为编译器可以根据变量的值来自己推断其类型,就像scala中一样。
多个相同类型的声明可以简写,不用一个一个单独定义:
const str1, str2 = "zhangsan", "lisi"
不同类型也可以进行多重赋值:
const a, b, c = 1, false, "str"
用作枚举
const (
gender = 0
male = 1
female = 2
)
数字 0、1 和 2 分别代表未知性别、男性和女性。
常量可以用len(), cap(), unsafe.Sizeof()函数计算表达式的值。
常量表达式中,函数必须是内置函数,否则编译不过。
示例:
package main
import "unsafe"
const (
a = "abc"
b = len(a)
c = unsafe.Sizeof(a)
)
func main(){
println(a, b, c)
}
//运行结果为:
abc 3 16
//因为Golang中的string内部实现由两部分组成,一部分是指向字符串起始地址的指针,另一部分是字符串的长度,两部分各是8字节,所以一共16字节
iota
iota,特殊常量,可以认为是一个可以被编译器修改的常量。
iota 在 const关键字出现时将被重置为 0(const 内部的第一行之前),const 中每新增一行常量声明将使 iota 计数一次(iota 可理解为 const 语句块中的行索引)。
iota 可以被用作枚举值:
const (
a = iota
b = iota
c = iota
)
第一个 iota 等于 0,每当 iota 在新的一行被使用时,它的值都会自动加 1;
所以 a=0, b=1, c=2 可以简写为如下形式:
const (
a = iota //0
b //1
c //2
)
iota 用法:
package main
import "fmt"
func main() {
const (
a = iota //0
b //1
c //2
d = "ha" //独立值,iota += 1
e //"ha" iota += 1
f = 100 //iota +=1
g //100 iota +=1
h = iota //7,恢复计数
i //8
)
fmt.Println(a,b,c,d,e,f,g,h,i)
}
运行结果为:
0 1 2 ha ha 100 100 7 8
当赋值时,还是会默认在自动加1,但是不会把加的值做为最后的值,没有新的赋值,后面的值都引用上一次的值;但再次出现iota时,恢复相加后的值做为赋给后的值,如果后面没有再出现新的赋值,就会以自加的值做为最后的值,以此类推。
示例:
package main
import "fmt"
const (
a=1<<iota //1
b=3<<iota //3*2^1
c //3*2^2
d //3*2^3
)
func main() {
fmt.Println("a=",a)
fmt.Println("b=",b)
fmt.Println("c=",c)
fmt.Println("d=",d)
}
运行结果为:
a= 1
b= 6
c= 12
d= 24
iota 表示从 0 开始自动加 1,所以 a=1<<0, b=3<<1(<< 表示左移的意思),即:a=1, b=6,这没问题,关键在 c 和 d,从输出结果看 c=3<<2,d=3<<3。
解析:
a=1:左移 0 位,不变仍为 1:
- b=3:左移 1 位,变为二进制 110, 即 6;
- c=3:左移 2 位,变为二进制 1100, 即 12;
- d=3:左移 3 位,变为二进制 11000,即 24。
算法:
m<<n==m*(2^n),表示m*2的N次方。