go——常量

常量是一个简单值的标识符,在程序运行时,不会被修改的量
常量中的数据类型只可以是布尔值、数字型(整数型、浮点型和复数)和字符串。
常量的定义格式:

const identifier [type] = value

你可以省略类型说明符[type],因为编译器可以根据变量的值来推断其类型。
显式定义:

const b string = “abc”

隐式定义:

const b = “abc”

多个相同类型的声明可以简写为:

const c_name1,c_name2 = value1,value2

 

下面是一个综合示例:

package main

const x int = 100 //显式定义
const y = false //隐式定义
const m, n = 111, 222 //一次定义多个,前提条件是类型一致

func main() {
const ( //以组的方式批量定义
i, f = 0, 1
b = false
)
}

需要说明的是定义常量但是不使用常量并不会报错。
如果显式定义常量,必须保证常量左右两边的类型必须一致,需要的时候可以做显式转化。
同时,右值不能超出常量类型取值范围,否则会引发溢出错误。

const k uint8 = 999 //constant 999 overflows uint8,uint8的最大取值是255

常量也可以是某些编译器能计算出结果的表达式。

const (
	ptrSize = unsafe.Sizeof(uintptr(0))
	strSize = len("hello, world")
)

在常量组中如不指定类型和初始化值,则与上一行非空常量右值相同。

package main

import "fmt"

func main() {
	const (
		x int = 18
		y           //与上一行x类型和值相同
		z = "abc"
		s
	)
	fmt.Printf("%T, %v\n", y, y)
	fmt.Printf("%T, %v\n", s, s)
}

/*
结果:
int, 18
string, abc
*/

  

iota

iota,特殊常量,可以认为是一个可以被编译器修改的常量。
iota在const关键字出现时将被重置为0(const内部的第一行之前),
const中每新增一行常量声明将使iota计数一次(iota可以理解为const语句块中的行索引。)

const (
	a = iota
	b = iota
	c = iota
)

第一个iota等于0,每当iota在新的一行被使用时,它的值都会自动加1,所以a=0,b=1,c=2,
可以简写为如下形式:

const (
	a = iota
	b
	c	
)

看几个简单的例子:
示例1:

package main

import "fmt"

const (
	_  = iota
	kb = 1 << (10 * iota)  
	mb                     
	gb					
)
/*
gb和mb的值与kb的值相同
(kb = 1) << (10 * 1)  1 * 2**10 = 1024
(mb = 1) << (10 * 2)  1 * 2**20 = 1048576
(gb = 1) << (10 * 3)  1 * 2**30 = 1073741824
*/
//iota值是自增的,向左移动n位,就是乘以2的n次方

func main() {
	fmt.Println(kb, mb, gb)
}
/*
结果:
1024 1048576 1073741824
*/

  

示例2:

package main

import "fmt"

func main() {
	const (
		a = iota  //0
		b         //1
		c         //2
		d = "hello"  //重新赋值,但是iota +=1
		e            //引用上面,但是iota +=1
		f = 100      //重新赋值
		g
		h = iota     //7  如果中断iota自增,必须显式恢复
		i            //8
	)
	fmt.Println(a, b, c, d, e, f, g, h, i)
}

//a, b, c, d,    e,    f,  g,  h, i
//0  1  2  hello hello 100 100 7  8


常量与变量本质的差别
不同于变量在运行期间分配存储内存,常量通常会被编译器在预处理阶段直接展开,作为指令数据使用

package main

import "fmt"

var x = 0x100

const y = 0x200

func main() {
	fmt.Println(&x, x)
	fmt.Println(&y, y)  //cannot take the address of y  无法获取内存地址
}

数字常量不会被分配存储空间,无需像变量那样通过内存来取值,因此无法获取内存地址。

posted @ 2018-12-08 23:39  明王不动心  阅读(257)  评论(0编辑  收藏  举报