Go语言 常量

导言

  • 原文链接: Part 5: Constants
  • If translation is not allowed, please leave me in the comment area and I will delete it as soon as possible.

常量

定义

Go 中,我们把一些固定的值叫做常量,例如 5-89"I love Go"67.89

看看下面的代码先:

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

在上面的代码中,我们把常量 50"I love Go" 分别分配给 ab

我们可以使用 关键字const 定义常量。虽然在上面的代码中,我并没有显式地使用 const,但实际在 Go 中,50"I love Go" 就是常量。

再来看个程序:

package main

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

我们无法给常量重新赋值,因此上面的程序会出现编译错误:

cannot assign to a.

函数与常量

在编译时,常量的数值必须是确定的。因此函数的返回值不能分配给常量,因为函数调用发生在运行时期。

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 是一个常量,它的值必须在编译时期确定。因为在运行时,math.Sqrt(4) 的值才被算出,所以执行 const b = math.Sqrt(4) 时,会抛出一个错误:

main.go:11: const initializer math.Sqrt(4) is not a constant.

字符串常量

Go 中,被双引号括起的值 就是 字符串常量。举个例子,“Hello World""Sam" 都是字符串常量。

字符串常量的类型是什么?答案是 无类型 (untyped)

字符串常量没有类型!

const hello = "Hello World"  

在上面的代码中,我们将 "Hello World" 分配给字符串常量 hello。此时 hello 是没有类型的。

Go 是强类型语言。所有的变量都有一个显性的类型。那么,在下面的程序中,如果我们把 无类型的常量"Sam" 分配给 变量name,这会发生什么?

package main

import (  
    "fmt"
)

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

答案就是:常量都有一个与之相关联的默认类型,当有一行代码用到该常量时,该常量才表现出默认类型。

在上面的 var name = "Sam"语句 中,name 是需要类型的,而这个类型来自 常量"Sam" 的默认类型 — string

我们能创建有类型的常量吗?答案是肯定的,代码如下:

const typedhello string = "Hello World"  

在上面的代码中,typehello 就是一个类型为 string 的常量。

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,所以分配后,defaultName 的类型是 string

在下一行,我们定义了一个新的类型 myString,它来自 string类型。

之后,我们创建了一个 变量customName,并将 常量"Sam" 也分配给它。因为 常量"Sam" 是无类型的,所以它能分配给任何 string类型 的变量。因此,这个分配也是允许的,分配后,customName 的类型为 myString

现在,我们拥有了 string类型 的 defaultName,以及 myString类型 的 customName。但是,即使 myString 是以 string 为基础创建的,Go语言 的类型政策还是不允许将 string类型 变量,分配给 myString类型 变量。

因此,customName = defaultName 并不能执行,编译器会抛出一个错误:

main.go:7:20: cannot use defaultName (type string) as type myString in assignment

布尔常量

布尔常量和字符串常量差别不大,只不过布尔常量只有两个取值:truefalse。由于适用于字符串常量的规则,同样适用于布尔常量,这里我就不赘述了。

下面是一个关于布尔常量的简单例子:

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,而它的句式是通用的 (它可以代表 浮点数、整数、甚至是没有虚部的复数),所以它能被分配给任何兼容的类型 — 这一类常量的默认类型,可以认为是根据上下文动态生成的

var intVar int = a 要求 aint类型,所以 a 变为了 int类型 常量。
var complex64Var complex64 = a 要求 acomplex64类型,所以 a 变为了 complex64类型 常量。


数字表达式

数字常量的任意混合搭配 构成了 数字表达式,数字表达式也可看作数字常量。

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.98 都是数字常量,所以表达式 5.9/8 能通过编译。这个表达式的结果是 0.7375,它是一个浮点数常量,因此 变量a 也为浮点数。

运行上面的程序,输出如下:

a's type float64 value 0.7375.

这就是常量了~

祝你吃好睡好身体棒~


原作者留言

优质内容来之不易,您可以通过该 链接 为我捐赠。


最后

感谢原作者的优质内容。

欢迎指出文中的任何错误。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值