Go 语言基础-常量

点击上方蓝色“Golang来啦”关注我哟

加个“星标”,天天 15 分钟,掌握 Go 语言

你好,我是四哥。

上篇文章我们讲了类型,今天来学习下常量。

什么是常量?

Go 语言里面使用常量表示固定不变的值,例如:

95
"I love Go"
67.89

声明常量

关键字 const 用来声明一个常量,一起来看下 Go 语言该如何声明常量:

package main

import (
    "fmt"
)

func main() {
    const a = 50
    fmt.Println(a)
}

执行[1]

上面的代码声明了常量 a,并赋值为 50。

声明一组变量

Go 语言提供了在单个语句块中声明一组常量的语法,来看下示例:

package main

import (
    "fmt"
)

func main() {
    const (
        name = "John"
        age = 50
        country = "Canada"
    )
    fmt.Println(name)
    fmt.Println(age)
    fmt.Println(country)

}

执行[2]

上面的代码,我们声明了一组常量:name、age 和 country,执行输出:

John
50
Canada

常量,顾名思义,是固定不变的,声明之后是不能再重新赋给其他值的。下面的代码中,我们尝试给常量 a 再次赋值为 89,这是不允许的,因为 a 是常量,编译会报错 cannot assign to a。

package main

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

执行[3]

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

package main

import (
    "math"
)

func main() {
    var a = math.Sqrt(4)   //allowed
    const b = math.Sqrt(4) //not allowed
}

执行[4]

上面的代码中,a 是一个变量,所以可以通过函数 math.Sqrt(4) 的返回值初始化。

b 是常量,它的值在编译时就需要确定,而函数 math.Sqrt(4) 的返回值在运行时确定,所以编译会报错:

./prog.go:9:8: const initializer math.Sqrt(4) is not a constant

字符串常量、类型确定常量和无类型常量

Go 语言里面,使用双引号括起来来的任何值表示字符串常量,例如:"Hello World", "Sam" 等。

字符串常量属于什么类型呢?答案是类型不确定

const hello = "Hello World"

上面的代码,没有为常量 hello 指定类型。

Go 是强类型语言,所有变量的类型都是明确的。

下面的代码,将无类型的常量 n 赋值给变量 name 的机制是怎样的呢?

package main

import (
    "fmt"
)

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

}

执行[5]

未定义类型的常量被使用时,会根据上下文来获得相关类型。

例如上面代码的第 9 行,编译器会自动推断常量 n 的类型为 string。

那有没有创建指定类型的常量呢?

当然是有的,比如下面这样:

const typedhello string = "Hello World"

typedhello 是 string 类型的常量。

Go 是强类型语言,不同类型之间相互赋值时不允许的。我们看下这个例子:

package main

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

}

执行[6]

上面的代码,我们创建了变量 defaultName 并赋值为常量 Sam,因为 Sam 的默认类型为 string,所以变量 defaultName 的类型也是 string。

接着下一行代码,使用关键字 type 创建了新的类型 myString,底层类型是 string。

接着我们创建了 myString 类型的变量 customName,并将常量 Sam 赋值给它。因为 Sam 未指定类型,所以可以用它给任意字符串变量赋值。

现在变量 defaultName 的类型是 string,变量 customName 的类型是 myString,尽管两者的底层类型相同,但还是不允许相互赋值,所以最后一行代码会编译报错:

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

布尔常量

布尔常量与字符串常量类似,不过布尔常量只有两个值:true 和 false。字符串常量的使用规则同样适用于布尔常量,就不在这重复说明,来看个例子:

package main

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

执行[7]

大家可以自行分析上面的代码。

数值常量

数值常量包括整型、浮点和复数,数值常量有一些特别的地方,一起看下:

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)
}

执行[8]

看上面的代码,a 是无类型的常量,值为 5。可能你很想知道 a 的类型到底是什么?为什么它能赋值给不同的类型的变量?

这取决于我们如何使用 a,下面这个例子可以帮助我们理解:

package main

import (
    "fmt"
)

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

}

执行[9]

上面的代码,每个变量的类型取决于各自赋值的常量,5 是整型,5.6 是浮点数,5 + 6i 是复数,所以输出:

i's type is int, f's type is float64, c's type is 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 表示的数值是比较通用的,它可以表示整型、浮点数甚至是不带虚数的复数,因此它可以分配给任何兼容的类型。常量的类型可以认为是根据上下文动态生成的。比如,var intVar int = a 场景中 a 是 int,var complex64Var complex64 = a 语句中 a 是 复数类型,等等。

数值表达式

可以在表达式中自由组合混用数值类型,并且只有在将它们分配给变量或需要确定类型的地方才需要类型。

package main

import (
    "fmt"
)

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

执行[10]

上面的代码中,在语法上,5.9 表示 float、8 表示 int,尽管如此,5.9/8 依然是允许的,因为它们都是数值常量。相除的结果是 0.7375,float 类型,因此变量 a 的类型是浮点数。

程序输出:

a's type is float64 and value is 0.7375

参考资料

[1]

执行: https://go.dev/play/p/mv3B-q3h0zh

[2]

执行: https://go.dev/play/p/KvZ6zNz4A04

[3]

执行: https://go.dev/play/p/b2J8_UQobb

[4]

执行: https://go.dev/play/p/GBlQDcbqfn-

[5]

执行: https://go.dev/play/p/oFv_cFuEucL

[6]

执行: https://go.dev/play/p/1Q-vudNn_9

[7]

执行: https://go.dev/play/p/h9yzC6RxOR

[8]

执行: https://go.dev/play/p/a8sxVNdU8M

[9]

执行: https://go.dev/play/p/0-eVCbJ76B5

[10]

执行: https://go.dev/play/p/Nsak9scUAWg

via: https://golangbot.com/constants/
作者:Naveen R


这是持续翻译的第 30/100 篇优质文章,
如果你有想交流的话题,欢迎留言。


推荐阅读:

如何制定目标才能让自己的学习效果更好?

资料下载

点击下方卡片关注公众号,发送特定关键字获取对应精品资料!

  • 回复「电子书」,获取入门、进阶 Go 语言必看书籍。

  • 回复「视频」,获取价值 5000 大洋的视频资料,内含实战项目(不外传)!

  • 回复「路线」,获取最新版 Go 知识图谱及学习、成长路线图。

  • 回复「面试题」,获取四哥精编的 Go 语言面试题,含解析。

  • 回复「后台」,获取后台开发必看 10 本书籍。

对了,看完文章,记得点击下方的卡片。关注我哦~ 👇👇👇

如果您的朋友也在学习 Go 语言,相信这篇文章对 TA 有帮助,欢迎转发分享给 TA,非常感谢!292b437fdec4a49827c22ca7bc0a5675.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Seekload

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值