Golang教程:常量


定義常量

常量(constant)表示固定的值,比如: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 修飾 50 與 "I love Go",但它們在Go的內部表示為常量。

關鍵字 const 修飾的名字為常量,不能被重新賦予任何值。 因此下面的程序會報錯: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 是一個常量,它的值必須在編譯期間確定,但是函數 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" 都是字符串常量。

字符串常量是什么類型呢?答案是 無類型(untyped)。

像 "Hello World" 這樣的字符串沒有任何類型。

const hello = "Hello World" 

上面的代碼將 "Hello World" 賦給一個名為 hello 的常量。那么現在常量 hello 是不是就有了類型?答案是:No。hello仍然沒有類型。

下面的代碼中,變量 name 被賦值為一個無類型的常量 "Sam",它是如何工作的呢?

package main

import (  
    "fmt"
)

func main() {  
    fmt.Println("Hello, playground")
    var name = "Sam"  // 譯者注:這里編譯器需要推導出 name 的類型,
                      // 那么它是如何從無類型的常量 "Sam" 中獲取類型的呢?
    fmt.Printf("type %T value %v", name, name)

}

答案是無類型常量有一個默認的類型,當且僅當代碼中需要無類型常量提供類型時,它才會提供該默認類型。在語句 var name = "Sam" 中,name需要一個類型,因此它從常量 "Sam" 中獲取其默認類型:string。

有沒有辦法創建一個有類型(typed)的常量?答案是:Yes。下面的代碼創建了一個有類型常量

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,因此賦值之后,defaultName 的類型亦為 string

下一行我們創建了一個新的類型 myString,它是 string 的別名。

譯者注:可以通過 type NewType Type 的語法來創建一個新的類型。類似 C 語言的 typedef 。

接着我們創建了一個名為 customName 的 myString 類型的變量,並將常量 "Sam" 賦給它。因為常量 "Sam" 是無類型的所以可以將它賦值給任何字符串變量。因此這個賦值是合法的,customName 的類型是 myString

現在我們有兩個變量:string 類型的 defaultName 和 myString 類型的 customName。盡管我們知道 myString 是 string的一個別名,但是Go的強類型機制不允許將一個類型的變量賦值給另一個類型的變量。因此, customName = defaultName 這個賦值是不允許的,編譯器會報錯:main.go:10: 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
}

上面的程序很好理解,這里就不過多解釋了。

數值常量

數值常量(Numeric constants)包括整數,浮點數以及復數常量。數值常量有一些微妙之處。

讓我們看一些例子使事情變得明朗。

package main

import (  
    "fmt"
)

func main() {  
    fmt.Println("Hello, playground")
    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() {  
    fmt.Println("Hello, playground")
    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

譯者注:編譯器可以根據字面值常量的表現形式來確定它的默認類型,比如 5.6 表現為浮點數,因此它的默認類型為 float64 ,而 "Sam" 表現為字符串,因此它的默認類型為 stirng

現在應該很清楚下面的程序是如何工作的了:

package main

import (  
    "fmt"
)

func main() {  
    fmt.Println("Hello, playground")
    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 在語法上是泛化的(它既可以表示浮點數 5.0,也可以表示整數 5,甚至可以表示沒有虛部的復數 5 + 0i),因此 a 可以賦值給任何與之類型兼容的變量。像 a 這種數值常量的默認類型可以想象成是通過上下文動態生成的。var intVar int = a 要求 a 是一個 int,那么 a 就變成一個 int 常量。var complex64Var complex64 = a 要求 a 是一個 complex64,那么 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.9/8 是合法的。相除的結果為 0.7375,是一個浮點數。因此變量 a 的類型為浮點型。上面的程序輸出為:a's type float64 value 0.7375

 

 

 

 

本文摘自:https://blog.csdn.net/u011304970/article/details/74857146


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM