變數
Golang是靜態型別語言,不能在執行期間改變變數型別。
變數
var 語句定義了一個變數的列表;跟函式的引數列表一樣,型別在後面。
初始化變數
使用關鍵字 var 定義變數,自動初始化為零值。如果提供初始化值,可省略變數型別,由編譯器自動推斷。
package main var x int var f float32 = 1.6 var s = "abc" func main() { }
一次性定義多個變數。
package main var x, y, z int var s, n = "abc", 123 var ( a int b float32 ) func main() { n, s := 0x1234, "Hello, World!" println(x, s, n) }
輸出結果:
0 Hello, World! 4660
多變數賦值時,先計算所有相關值,然後再從左到右依次賦值。
package main import "fmt" func main() { data, i := [3]int{0, 1, 2}, 0 i, data[i] = 2, 100 // (i = 0) -> (i = 2), (data[0] = 100) fmt.Println(i, data) }
輸出結果:
2 [100 1 2]
變數定義可以包含初始值,每個變數對應一個。
package main var i, j int = 1, 2 func main() { }
如果初始化是使用表示式,則可以省略型別;變數從初始值中獲得型別。
package main var c, python, java = true, false, "no!" func main() { }
短宣告變數
在函式內部,可以使用更簡略的 ":=" 方式定義變數。":=" 簡潔賦值語句在明確型別的地方,可以用於替代 var 定義。
package main import ( "fmt" ) var c, python, java = true, false, "no!" func main() { k := 3 c, python, java := false, true, "yes!" fmt.Println(c, python, java, k) //注意檢查,是定義新的區域性變數,還是修改全域性變數。該方式容易造成錯誤! }
輸出結果:
false true yes! 3
函式外的每個語句都必須以關鍵字開始( var 、 func 、等等), ":=" 結構不能使用在函式外。
特殊只寫變數 "_",用於忽略值佔位。
package main func test() (int, string) { return 1, "abc" } func main() { _, s := test() println(s) }
輸出結果:
abc
編譯器會將未使 的區域性變數當做錯誤。
package main var s string // 全域性變數沒問題。 func main() { i := 0 // ./main.go:6:7: i declared and not used (可使"_ = i" 規避) }
注意重新賦值與定義新同名變數的區別。
package main func main() { s := "abc" println(&s) s, y := "hello", 20 // 重新賦值: 與前 s 在同 層次的程式碼塊中,且有新的變數被定義。 println(&s, y)// 通常函式多返回值 err 會被重複使用。 { s, z := 1000, 30 // 定義新同名變數: 不在同 層次程式碼塊。 println(&s, z) } }
輸出結果:
0xc42003df60 0xc42003df60 20 0xc42003df58 30
Go 語言變數作用域
作用域為已宣告識別符號所表示的常量、型別、變數、函式或包在原始碼中的作用範圍。
Go 語言中變數可以在三個地方宣告:
函式內定義的變數稱為區域性變數 函式外定義的變數稱為全域性變數 函式定義中的變數稱為形式引數
接下來讓我們具體瞭解區域性變數、全域性變數和形式引數。
區域性變數
在函式體內宣告的變數稱之為區域性變數,它們的作用域只在函式體內,引數和返回值變數也是區域性變數。
以下例項中 main() 函式使用了局部變數 a, b, c:
package main import "fmt" func main() { /* 宣告區域性變數 */ var a, b, c int /* 初始化引數 */ a = 10 b = 20 c = a + b fmt.Printf("結果: a = %d, b = %d and c = %d\n", a, b, c) }
輸出結果:
結果: a = 10, b = 20 and c = 30
全域性變數
在函式體外宣告的變數稱之為全域性變數,全域性變數可以在整個包甚至外部包(被匯出後)使用。
全域性變數可以在任何函式中使用,以下例項演示瞭如何使用全域性變數:
package main import "fmt" /* 宣告全域性變數 */ var g int func main() { /* 宣告區域性變數 */ var a, b int /* 初始化引數 */ a = 10 b = 20 g = a + b fmt.Printf("結果: a = %d, b = %d and g = %d\n", a, b, g) }
輸出結果:
結果: a = 10, b = 20 and g = 30
Go 語言程式中全域性變數與區域性變數名稱可以相同,但是函式內的區域性變數會被優先考慮。例項如下:
package main import "fmt" /* 宣告全域性變數 */ var g int = 20 func main() { /* 宣告區域性變數 */ var g int = 10 fmt.Printf("結果: g = %d\n", g) }
輸出結果:
結果: g = 10
形式引數
形式引數會作為函式的區域性變數來使用。例項如下:
package main import "fmt" /* 宣告全域性變數 */ var a int = 20 func main() { /* main 函式中宣告區域性變數 */ var a int = 10 var b int = 20 var c int = 0 fmt.Printf("main()函式中 a = %d\n", a) c = sum(a, b) fmt.Printf("main()函式中 c = %d\n", c) } /* 函式定義-兩數相加 */ func sum(a, b int) int { fmt.Printf("sum() 函式中 a = %d\n", a) fmt.Printf("sum() 函式中 b = %d\n", b) return a + b }
輸出結果:
main()函式中 a = 10 sum() 函式中 a = 10 sum() 函式中 b = 20 main()函式中 c = 30
不同型別的區域性和全域性變數預設值:
全域性:
package main import "fmt" var b bool var i int var i8 int8 var i16 int16 var i32 int32 var i64 int64 var ui uint var ui8 uint8 var ui16 uint16 var ui32 uint32 var ui64 uint64 var f32 float32 var f64 float64 var s string func main() { fmt.Printf("全域性變數: bool 預設值:%v\n", b) fmt.Printf("全域性變數: int 預設值:%v\n", i) fmt.Printf("全域性變數: int8 預設值:%v\n", i8) fmt.Printf("全域性變數: int16 預設值:%v\n", i16) fmt.Printf("全域性變數: int32 預設值:%v\n", i32) fmt.Printf("全域性變數: int64 預設值:%v\n", i64) fmt.Printf("全域性變數: int64 預設值:%v\n", i64) fmt.Printf("全域性變數: uint 預設值:%v\n", ui) fmt.Printf("全域性變數: uint8 預設值:%v\n", ui8) fmt.Printf("全域性變數: uint16 預設值:%v\n", ui16) fmt.Printf("全域性變數: uint32 預設值:%v\n", ui32) fmt.Printf("全域性變數: uint64 預設值:%v\n", ui64) fmt.Printf("全域性變數: uint64 預設值:%v\n", ui64) fmt.Printf("全域性變數: float32 預設值:%v\n", f32) fmt.Printf("全域性變數: float64 預設值:%v\n", f64) fmt.Printf("全域性變數: string 預設值:%v\n", s) }
輸出結果:
全域性變數: bool 預設值:false 全域性變數: int 預設值:0 全域性變數: int8 預設值:0 全域性變數: int16 預設值:0 全域性變數: int32 預設值:0 全域性變數: int64 預設值:0 全域性變數: int64 預設值:0 全域性變數: uint 預設值:0 全域性變數: uint8 預設值:0 全域性變數: uint16 預設值:0 全域性變數: uint32 預設值:0 全域性變數: uint64 預設值:0 全域性變數: uint64 預設值:0 全域性變數: float32 預設值:0 全域性變數: float64 預設值:0 全域性變數: string 預設值:
區域性:
package main import "fmt" func main() { var b bool var i int var i8 int8 var i16 int16 var i32 int32 var i64 int64 var ui uint var ui8 uint8 var ui16 uint16 var ui32 uint32 var ui64 uint64 var f32 float32 var f64 float64 var s string fmt.Printf("區域性變數: bool 預設值:%v\n", b) fmt.Printf("區域性變數: int 預設值:%v\n", i) fmt.Printf("區域性變數: int8 預設值:%v\n", i8) fmt.Printf("區域性變數: int16 預設值:%v\n", i16) fmt.Printf("區域性變數: int32 預設值:%v\n", i32) fmt.Printf("區域性變數: int64 預設值:%v\n", i64) fmt.Printf("區域性變數: int64 預設值:%v\n", i64) fmt.Printf("區域性變數: uint 預設值:%v\n", ui) fmt.Printf("區域性變數: uint8 預設值:%v\n", ui8) fmt.Printf("區域性變數: uint16 預設值:%v\n", ui16) fmt.Printf("區域性變數: uint32 預設值:%v\n", ui32) fmt.Printf("區域性變數: uint64 預設值:%v\n", ui64) fmt.Printf("區域性變數: uint64 預設值:%v\n", ui64) fmt.Printf("區域性變數: float32 預設值:%v\n", f32) fmt.Printf("區域性變數: float64 預設值:%v\n", f64) fmt.Printf("區域性變數: string 預設值:%v\n", s) }
輸出結果:
區域性變數: bool 預設值:false 區域性變數: int 預設值:0 區域性變數: int8 預設值:0 區域性變數: int16 預設值:0 區域性變數: int32 預設值:0 區域性變數: int64 預設值:0 區域性變數: int64 預設值:0 區域性變數: uint 預設值:0 區域性變數: uint8 預設值:0 區域性變數: uint16 預設值:0 區域性變數: uint32 預設值:0 區域性變數: uint64 預設值:0 區域性變數: uint64 預設值:0 區域性變數: float32 預設值:0 區域性變數: float64 預設值:0 區域性變數: string 預設值: