聽 通常情况下语言入门前会讲一堆背景和特性,目的是为了能让学习者对该语言有一个大概的认识,但这里我想直接进入细节,不是因为任性,而是因为常量是编程语言最基本的组成元素,这与语言背景无关。
一、字面常量
在说明字面常量之前先说一下魔鬼数字,哪么什么是魔鬼数字呢?
func calculatePrice(price float32) float32{
聽 return price * 0.8
}
这个方法中的0.8就是魔鬼数字(没有具体含义),它导致代码难以理解,这里的0.8表示折扣的意思,为了清晰起见,上面的代码可以如下修改:
const discount float64 = 0.8 // 定义折扣常量
func calculatePrice(price float32) float32{ // 计算折扣后的价格
聽 return price *聽discount
}
这个例子中的魔鬼数字就是字面常量的一种,除了浮点型之外,还可以有整型、布尔型、字符串型等字面常面,如:
3.1415926535897932 // 浮点类型的字面常量
-12 聽 聽 聽 聽 聽 //整数类型的字面常量
true 聽 聽 聽 聽 聽//布尔类型的字面常量
"ok" 聽 聽 聽 聽 聽//字符串类型的字面常量
当然GO还有复数常量,如3+2i
二、常量
和其它语言(C、C++、Java等)类似,由const关键字修饰,例如:
const PI float64 = 3.1415926535897932
const EluerE float64 = 2.718281828459045
const value int = -12
const width int = 36
const flag bool = false
const isRead bool = true
const str string = "ok"
const bookName string = "Go language"
const rect complex64 = 3 + 2i
const area complex64 = 3.1415 + 3.6i
每个常量定义的形式都必须写成const constName constType = constValue这种形式吗?我们是否能省略掉常量类型?当然可以,要知道GO语言是最懂程序员的哟 :)
const PI = 3.1415926535897932
const EluerE = 2.718281828459045
const value = -12
const width = 36
const flag = false
const isRead = true
const str = "ok"
const bookName = "Go language"
const rect = 3 + 2i
const area = 3.1415 + 3.6i
每个常量定义都要写一次const,是否能省略掉const?这个是不可以的,但可以把上面的定义写成如下形式:
const (
聽 聽 PI = 3.1415926535897932
聽 聽 EluerE = 2.718281828459045
聽 聽 value = -12
聽 聽 width = 36
聽 聽 flag = false
聽 聽 isRead = true
聽 聽 str = "ok"
聽 聽 bookName = "Go language"
聽 聽 rect = 3 + 2i
聽 聽 area = 3.1415 + 3.6i
)
这样写虽然少写了const,但代码行数并没有减少,所以也可以缩写为:
const (
聽 聽PI, EluerE, value, width, flag, isRead, str, bookName, rect, area = 3.1415926535897932, 2.718281828459045, -12, 36, false, true, "ok", "Go language", 3 + 2i, 3.1415 + 3.6i
)
三、常量特点说明
1、没有private、protected、public修改符
有过Java开发经验的读者都清楚private、protected、public修饰符,但GO对你说sorry。GO是怎么区分常量/变量是对内还是对外的呢?
答案是常量名的首字母是否大写,若首字母大写则是对外的,首字母小写则是对内的,上例中的PI、EluerE就相当于public的,而value、width、flag、isRead等就相当于private
2、类型放在常量名的后面
有过Java开发经验的读者都比较熟悉public int value = 10这种定义方式,类型放在变量名value的前面,但GO恰恰相反,偏偏把类型放在后面,例如:const PI float64 = 3.1415926535897932
3、常量定义语句不用分号结束
在Java或C等语言中,一般都是这样定义:const str string = "ok";但在GO中懒得把分号(;)都省略了。刚开始写GO代码很不习惯,总是在后面追加一个分号,然而一保存Sublime text很贴心地帮我省略掉了
4、常量定义的右值可以是一个编译期运算的常量表达式
例如:
const聽algorithm = 255 >> 2
这点与其它语言类似,也容易理解,若右值是运行期才能得到的结果表达式
const Port = os.GetEnv("Port")
那么在编译期并不能确定该值,会出现编译错误
四、预定义常量iota
iota是GO所特有的,它在每个const出现时被重置为0,下一个const出现之前,每出现一次iota,其所代表的数字自动增加1,那么怎么理解这句话呢?
【例1】:我们定义一个星期的枚举常量
const (
聽 聽 Sunday 聽 聽= iota 聽//星期天
聽 聽 Monday 聽 聽= iota 聽//星期一
聽 聽 Tuesday 聽 = iota 聽 //星期二
聽 聽 Wednesday = iota 聽 //星期三
聽 聽 Thursday 聽= iota 聽 //星期四
聽 聽 Friday 聽 聽= iota 聽//星期五
聽 聽 Saturday 聽= iota 聽 //星期六
)
当每个const出现时iota被重置为0,所以这里的Sunday值为0,同时后面没有再出现const,所以第二个iota自动加1,Monday的值为1,依次类推,Saturday的值为6
值得一提的是,上面的写法可以简写如下:
const (
聽 聽 Sunday = iota 聽//星期天
聽 聽 Monday 聽 聽 聽聽//星期一聽
聽 聽 Tuesday 聽 聽 聽//星期二
聽 聽 Wednesday 聽 聽聽//星期三
聽 聽 Thursday 聽 聽聽//星期四
聽 聽 Friday 聽 聽 聽聽//星期五
聽 聽 Saturday 聽 聽聽//星期六
)
【例2】:修改一下这个枚举定义
const (
聽 聽 Sunday 聽= iota //星期天,赋值为0
聽 聽 Monday 聽= iota //星期一
聽 聽 Tuesday = iota //星期二
)
const (
聽 聽 Wednesday = iota //星期三,赋值为0
聽 聽 Thursday 聽= iota //星期四
聽 聽 Friday 聽 聽= iota //星期五
聽 聽 Saturday 聽= iota //星期六
)
当每个const出现时iota被重置为0,所以这里的Sunday,Monday没有const出现,其值自动加1,所以Monday为1,同理Tuesday为2;聽
由于Wednesday之前出现了const,所以Wednesday的值被重置为0,而Thursday、Friday、Saturday后面再没有const出现,所以Thursday、Friday、Saturday值自动加1,依次为1、2、3
【编后话】:
开始接触GO,感觉它就是一个大杂烩,里面即有C语言的影子,也有Java语言的影子,也有JavaScript脚本的影子,同时还有Pascal语言的痕迹,但使用使用着感觉这符合人的正常思维,代码想怎么写就怎么写,无论怎么写好像都符合GO的语法。借用知乎用户的话讲:GO语言是一门看似简单实际并不简单,貌似外表丑陋实则另有考究的语言。
本文出自 “青客” 博客,请务必保留此出处http://qingkechina.blog.51cto.com/5552198/1614703
有疑问加站长微信联系(非本文作者)