golangbot
golangbot
发布于 3个月前

[ Golang 入门教程 ] 第5节——常量

定义

常量在Go中用于表示固定值,例如5,-89,“I love Go”,67.89等。

以下代码,

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

在上面的代码中,ab分配给常数 50I love Go。关键字 const 用于表示常量。即使我们在上面的代码中没有明确地使用关键字const,但在内部它们是Go中的常量。

定义为常量后不能再次重新分配给任何其他值,因此下面的程序将编译错误 cannot assign to a

package main

func main() {  
    const a = 55 //允许
    a = 89 //不允许
}

运行代码

在编译时应知道常量的值。因此,不能分配给常量 调用函数返回的值,因为函数调用是在运行程序时进行的。

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:11: const initializer math.Sqrt(4) is not a constant

字符串常量

双引号之间的任何值都是Go中的字符串常量。例如,像“Hello World”或“Sam”这样的字符串都是Go中的常量。

字符串常量属于什么类型?答案是他们是无类型的

像“Hello World”这样的字符串常量没有任何类型

const hello = "Hello World"  

在上面的例子中,我们为命名常量hello分配了“Hello World” 。现在常量hello有一个类型吗?答案是否定的。常数仍然没有类型。

Go是一种强类型语言。所有变量都需要显式类型。那么以下程序如何为变量name 分配无类型常量Sam

package main

import (  
    "fmt"
)

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

运行代码

*答案是无类型常量具有与它们相关联的默认类型,并且当且仅当一行代码需要它时才提供它。在语句中var name = "Sam"name需要一个类型,它从字符串常量“Sam”的默认类型获取它,这是一个字符串。*

有没有办法创建一个类型常量?答案是肯定的。以下代码创建一个类型常量。

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
}

运行代码

在上面的代码中,我们首先创建一个变量defaultName并将其分配给常量Sam常量Sam的默认类型是字符串,因此在赋值后,defaultName的类型为 字符串。

在下一行中,我们创建一个新类型 myString,它是 string 的别名。

然后我们创建一个myString类型的变量 customName 并将其分配给常量Sam。由于常量Sam是无类型的,因此可以将其分配给任何字符串变量。因此,这里允许赋值,并且customName获取myString类型。

现在我们有一个类型为string的变量defaultName和另一个类型为myString的变量customName。即使我们知道myString是字符串的别名,Go的强类型策略也不允许将一种类型的变量分配给另一种类型。因此,不允许赋值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)
}

运行代码

在上面的程序中,const 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 %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的语法是通用的(它可以表示浮点数,整数甚至是没有虚部的复数),因此可以将其分配给任何兼容类型。这些常量的默认类型可以被认为是根据上下文动态生成的。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是浮点数,因此变量a是float类型。该程序的输出是a's type float64 value 0.7375