定義常量
常量(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
