Go教程第五篇:常量

Go教程第五篇:常量

本文是《Go系列教程》的第五篇

定义

Go里面的常量术语是用于表示固定值,例如: 5,-89,"I love Go",67.89 等等。

思考一下下面的代码:

var a int = 50
var b string = "I love Go"

在上面的代码中,各自给a和b赋予常量值: 50和"I love Go"。
关键字 const用于表明常量值,如: 50和"I love Go"。即使在上面的代码中没有明确地使用const
关键字,在Go内部它们也是常量。

常量的值不能更改,因此 下面的程序无法运行,它会报编译期错误: cannot assign to a 。

package main

func main() {
    const a = 55 //allowed
    a = 89 //reassignment not allowed
}

常量的值在编译期都是可知的。因此,函数的返回值不能被赋予一个常量,因为函数调用只有在运行时期才发生。

package main

import (
    "fmt"
    "math"
)

func main() {
    fmt.Println("Hello, playground")
    var a = math.Sqrt(4)//allowed
    const b = math.Sqrt(4)//not allowed
}

在上面的程序中,a 是一个变量,因此可以把一个函数math.Sqrt(4)的返回值赋值给他。而 b是一个常量
所以b的值在编译期必须是可知的。函数math.Sqrt(4)只有在运行期才能计算出来。因此 const b=math.Sqrt(4)
会抛出一个错误: error main.go:II: const initializer math.Sqrt(4) is not a constant。

字符串常量

对Go来说,任何由双引号""包裹的值都是一个字符串常量。例如,"Hello World"或 "Sam"在Go里面 都是常量。
那么,究竟一个字符串常量属于什么类型呢?他们都是:untyped。

字符串常量比如"Hello World"没有任何数据类型。

const hello="hello world"

在上面的代码中,我们把"hello world" 赋值给一个命名的常量hello。那么现在这个常量hello有数据类型吗?
答案是: 没有。常量仍然没有数据类型。

Go是一个强类型的语言。所有的变量都需要一个明确的数据类型。那么为什么下面的程序就可以给变量name分配一个无类型的常量
Samne ???

package main

import (
    "fmt"
)

func main() {
    var name = "Sam"
    fmt.Printf("type %T value %v", name, name)

}

原因是: 无类型常量都有一个和他们相关联的默认数据类型,它会在而且仅仅会在某行代码需要它的时候被应用。在语句: var name="Same"
中,name需要一个数据类型,那么这时它就取字符串常量的默认数据类型,对于"Sam"来说,也就是:string。

那么有没有什么办法创建一个类型常量呢??,答案是有的。下面的代码会创建一个类型常量。

const typedhello string = "Hello World"

上述代码中的typedhello就是一个字符串类型的常量。

Go 是一个强类型的语言,在赋值时不允许混合类型。我们通过下面的例子来看一下:

package main

func main() {
        var defaultName = "Sam" //allowed
        type myString string
        var customName myString = "Sam" //allowed
        customName = defaultName //not allowed

}

在上面的代码中,我们首先创建了一个变量defaultName,并且给他分配一个常量Sam。常量Sam的默认数据类型是string。
因此在分配之后,defaultNamede的变量类型也是string。

在紧接着的下面一行,我们创建了一个新的类型:myString,它是string的别名。之后,我们创建了一个myString类型的变量customName.并把常量Sam赋值给他。因为常量Sam属于无类型的,所以它可以被赋值给任何string类型的变量。故而,赋值是合法的,并且customName的类型依然是myString。

到目前为止,我们有一个string类型的变量 defaultName 和 另一个myString类型的变量 customName。即使我们知道myString只是string的别名而已,Go的强类型约束仍然不会允许一个类型变量变量被赋值给另一个类型的变量。因此,customName = defaultName 是不合法的,
编译器会抛出:error main.go:7:20: cannot use defaultName (type string) as type myString in assignment错误。

布尔常量

布尔常量不同于字符串常量,他们是俩个无类型的常量: true和false。string常量的规则同样适用于布尔常量,我们就不再赘述。
下面这个简单的例子就是对布尔常量的解释:

package main

func main() {
    const trueConst = true
    type myBool bool
    var defaultBool = trueConst //allowed
    var customBool myBool = trueConst //allowed
    defaultBool = customBool //not allowed
}

数字常量

数字常量包括: 整型、浮点型和复杂类型。他们有一些细微的差别。

package main

import (
    "fmt"
)

func main() {
    const a = 5
    var intVar int = a
    var int32Var int32 = a
    var float64Var float64 = a
    var complex64Var complex64 = a
    fmt.Println("intVar",intVar, "\nint32Var", int32Var, "\nfloat64Var", float64Var, "\ncomplex64Var",complex64Var)
}

在上面的程序中,常量a是一个无类型的,值是5。你可能会想a的默认类型是什么,如果a有默认类型的话,为何我们可以把它赋值给另一个不同类型的变量。答案就在a的语法中。下面的程序会更清晰地说明这个问题。

package main

import (
    "fmt"
)

func main() {
    var i = 5
    var f = 5.6
    var c = 5 + 6i
    fmt.Printf("i's type %T, f's type %T, c's type %T", i, f, c)

}

在上面的程序中,每一个变量的类型都由数字常量的语法所决定。语法是的5是一个整型,5.6是一个浮点型,5+6i是一个复杂数字类型。当运行上述程序的时候,会输出:i's type int, f's type float64, c's type complex128 。

我们希望下面的程序的运行原理会更加清楚:

package main

import (
    "fmt"
)

func main() {
    const a = 5
    var intVar int = a
    var int32Var int32 = a
    var float64Var float64 = a
    var complex64Var complex64 = a
    fmt.Println("intVar",intVar, "\nint32Var", int32Var, "\nfloat64Var", float64Var, "\ncomplex64Var",complex64Var)
}

在这个程序中,a的值是5,并且a的语法是通用的(它可以代表ie浮点型、整型、甚至一个没有虚数部分的复杂数据类型)。因此,它可以被赋值给任何兼容的数据类型。你可以认为这些常量的默认数据类型都是由上下文决定的。
var intVar int = a 需要a是一个int类型,所以它就变成了一个int常量。var complex64Var complex64 = a需要a是一个复杂数字类型,因此它就变成了一个复杂数字常量。非常的灵巧。

数字表达式

在表达式中数字常量可以自由地混杂和匹配。只有在代码中要求有类型的时候,数字常量的类型才是必需的。

package main

import (
    "fmt"
)

func main() {
    var a = 5.9/8
    fmt.Printf("a's type %T value %v",a, a)
}

上面的程序中,语法使得5.9是一个浮点型,8是一个整型。5.9/8作为数字常量可以是浮点型和整型。除的结果是:0.7375,这是一个float。因此,变量a是一个浮点型。程序的输出就是:a's type float64 value 0.7375.

致谢

感谢您百忙之中阅读本文。如果有任何反馈和问题,请您在评论区留言。

备注

本文系翻译之作原文博客地址

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,490评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,581评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,830评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,957评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,974评论 6 393
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,754评论 1 307
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,464评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,357评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,847评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,995评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,137评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,819评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,482评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,023评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,149评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,409评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,086评论 2 355