1. 程式人生 > >Go語言基礎語法總結

Go語言基礎語法總結

# 1. 認識HelloWorld 在前面的[《Go的安裝和使用》](https://mp.weixin.qq.com/s/dMkXlVxg9LZ-Pn119ZnpDQ)這篇文章中已經寫過`HelloWorld.go`了,現在就來逐行認識一下它。 ```go package main import "fmt" func main() { fmt.Println("Hello, World!") } ``` 第1行:我們的Go程式是由**包**——`package`構成的,包的宣告形式為:`package <包名>`。該行的意思是:當前`HelloWorld.go`檔案屬於`main`包。 第2行:如果你使用過Java或Python,那你對import肯定不陌生。該行的意思是:匯入一個名為`fmt`的包。如果需要匯入多個包,有兩種寫法: ```go import "fmt" import "math" ``` 或者使用分組形式同時匯入多個包 ```go import ( "fmt" "math/rand" ) ``` 顯然第二種使用括號,以分組的形式匯入更加方便。 第3行:我們使用`func`關鍵字來宣告一個函式,在這個例子中,我們宣告的是`main`函式。如果你有過其他語言的程式設計經驗,肯定熟悉`main`函式的作用:程式的入口。 第4行:我們的函式內容放在函式的`{}`中,在該例中,呼叫了`fmt`包中的列印方法,由此可見,Golang語言呼叫函式的方法和Java、Python一樣使用小數點:`<包名>.<函式名>`。 看完這幾行簡單程式碼,我們發現:在Go語言中,並不需要分號`;`來結束語句。 # 2. 變數 ## 2.1. 命名規範 Go語言要求識別符號以一個字母或下劃線開頭,後面可以跟任意數量的字母、數字、下劃線。不能使用關鍵字作為識別符號 區分大小寫,變數`num`和變數`Num`是兩個變數。 ## 2.2. 宣告 Go語言的變數宣告方式和其他語言(如C、Java、Python)不太一樣。 比如,我們宣告一個為int型別的變數a: ```go var a int ``` 可以看出,Go語言宣告變數的方式為: ```go var <變數名> <變數型別> ``` 我們還可以同時宣告多個型別相同的變數: ```go var <變數名1>, <變數名2>, <變數名3>, ... <變數型別> ``` 使用分組同時宣告多個型別不同的變數: ```go var ( <變數名1> <變數型別1> <變數名2> <變數型別2> <變數名3> <變數型別3> ... ) ``` 下面是一個具體的例子: ```go package main import "fmt" var i bool//型別在後 func main() { var a, b, c int//多個 fmt.Println(i, a, b, c) } ``` ## 2.3. 初始化 當我們宣告變數時,可以對其進行初始化。當有初始值時,我們可以省略變數的型別,變數會根據對應的初始值獲取正確的型別。見下例: ```go package main import "fmt" var a int = 1 var b, c bool = true, false func main() { var i, j, k = 2, false, "行小觀" //省略變數型別 fmt.Println(a, b, c, i, j, k) k = "行小觀2號" //賦值操作 fmt.Println(k) } ``` 若我們在宣告變數時,不給變數賦初始值,則這些變數會被賦予“**零值**”。 這些零值為: 1. 數值型別為0 2. 布林型別為false 3. 字串為""(即空字串) 如果上例中的程式碼中的變數不進行初始化,即: ```go package main import "fmt" var a int var b, c bool func main() { var i int var j bool var k string fmt.Println(a, b, c, i, j, k) } ``` 則列印結果為:0 false false 0 false (變數k由於是空字串,所以打印出來了但是看不到) ## 2.4. 短變數宣告 前面介紹了當我們宣告變數時有以下幾種方式: ```go var i int //宣告一個int變數 var i, j, k int //同時宣告多個int變數 var i int = 1 //宣告一個int變數並初始化 var i, j, k int = 1, 2, 3 //同時宣告多個int變數並分別初始化 var i = 1 //省略型別,宣告一個int變數並初始化 var i, j, k = 1, 2, 3 //省略型別,同時宣告多個int變數並分別初始化 ``` 除此之外還有一種更簡潔的宣告變數的方式: ```go i := 1 i, j, k := 1, 2, 3 ``` 當我們使用`:=`宣告變數時,不用寫`var`也不用寫型別,但是這種方式**只能在函式內部使用**,不能在函式外部使用。當在函式外部宣告變數時,只能使用`var`。 ```go package main import "fmt" var a int = 1 //函式外部 func main() { var i, j int = 2, 3 //函式內部 k := 4 //只能在函式中使用 v1, v2, v3 := true, false, "行小觀" fmt.Println(a, i, j, k, v1, v2, v3) } ``` 此外,我們宣告的變數必須要使用,如果聲明瞭變數,但是沒使用,會在編譯時報錯。比如: ```go package main import "fmt" func main() { var i bool var j int //聲明瞭,但沒使用,會報錯 fmt.Println(i) } ``` 對於我們匯入的包也有此要求,即:匯入的包必須使用。 # 3. 資料型別 ## 3.1. 布林型別 布林型別為`bool`,值可取`true`或`false`,預設值為`false`。 ## 3.2. 字串型別 字串型別為`string`,預設為空字串`""`。 ## 3.3. 數值型別 整數型別分為: - 有符號數:`int`、`int8`、`int16`、`int32 (rune)`、`int64` - 無符號數:`uint`、`uint8 (byte)`、`uint16`、`uint32`、`uint64`、 其中`int`和`uint`的兩種型別的長度相同,取決於具體的編譯器,比如在32位系統上通常為32位,在64位系統上通常為64位。 像`int8`、`uint8`這些型別則是Go語言直接定義好位數的型別。`rune`、`byte`是`int32`、`uint8`的別名。 > 當我們需要使用整數時,應當儘量使用`int`型別。當然,如果你有特殊的理由使用其他整數型別,便另當他論。 浮點數型別有兩種:`float32`和`float64`,注意沒有所謂的`float`型別。 複數型別也有兩種:`complex64`和`complex128` 注意:**不同型別的變數之間不能直接進行賦值或其他運算**(比如加減乘除) ```go package main import "fmt" var ( a int = 1 b int8 = 2 c int16 ) func main() { c = b //不同型別之間進行賦值操作,[報錯1] d := a + b //不同型別之間進行相加運算,[報錯2] fmt.Printf("c = %v, d = %v", c, d) } ``` 以上程式碼在編譯過程中會報錯: > [報錯1]:cannot use b (type int8) as type int16 in assignment > > [報錯2]:invalid operation: a + b (mismatched types int and int8) ## 3.4. 型別轉換 前面一節說過:**不同型別的變數之間不能直接進行賦值或其他運算**,所以我們可以間接地做。 比如:將`int8`型別轉換為`int`型別,這樣就可以間接地進行賦值和其他運算。 **使用表示式`T(v)`將變數v的值的型別轉換為T**。注意是轉換的是**變數的值**,變數本身的型別不變。 ```go package main import "fmt" var ( a int = 1 b int8 = 2 c uint d int64 ) func main() { c = uint(b) //將變數b的值2的型別從int8轉換為uint d = int64(a) + int64(b) fmt.Printf("c(%T):%v = b(%T):%v\n", c, c, b, b) fmt.Printf("a(%T):%v + b(%T):%v = d(%T):%v\n", a, a, b, b, d, d) } ``` 注意:Go語言中的型別轉換是顯示的,表示式`T()`是必須的,不能省略。 # 4. 常量 常量是固定的值,值在程式執行期間不會改變。 常量可以定義為數值、字串、布林型別 常量的宣告方式和變數差不多,區別在於常量需要用`const`關鍵字修飾,不能使用`:=`進行宣告。 ```go package main import "fmt" const num int = 555 var a int = 1 func main() { const world = "世界" const truth = true fmt.Println("Hello,", world) fmt.Println("num = ", num) fmt.Println("a = ", a) fmt.Println("對嗎?", truth) } ``` # 5. 初識函式 如果你之前學習過C或者Java等語言,肯定已經對函式(方法)有了一定的認識。 簡單地來說,函式是對能完成某個功能的部分程式碼的抽象。當以後再需要該功能,我們只需要呼叫其對用的函式即可,不必再重複編寫程式碼。 ## 5.1. 函式的宣告 我們在前面的內容已經使用到了函式,即`main()`。我們使用`func`關鍵字宣告函式。 ```go func func_name() { } ``` ## 5.2. 函式的引數 Go語言中,函式可以有0個或多個引數。 ```go package main import "fmt" func printName(name string, age int) { fmt.Println("我叫", name, ", 今年", age, "歲了") } func sayHello() { fmt.Println("行小觀說:“你好”") } func main() { printName("行小觀", 1) sayHello() } ``` 如果你有多個引數的型別相同,你可以進行簡寫,只需要在這幾個相同的引數最後寫一遍型別即可。 ```go func foo(x int, y int, z int) 可以簡寫為: func foo(x, y, x int) ``` ## 5.3. 函式的型別和返回值 函式的型別在函式名之後。(儘快適應Go的這種風格:型別在變數名後) ```go package main import "fmt" func add(x int, y int) int { return x + y } func main() { fmt.Println(add(1, 2)) } ``` 當函式沒有返回值時,不需要寫函式的型別: ```go func sayHello() {//沒有返回值,不寫函式型別 fmt.Println("行小觀說:“你好”") } ``` 函式可以有**0個或多個返回值**。 多個返回值就意味著該函式有多個返回值型別: ```go package main import "fmt" func sumAndDiff(x, y int) (int, int) { //兩個返回值型別 sum := x + y diff := x - y return sum, diff //兩個返回值 } func main() { a, b := sumAndDiff(5, 1) fmt.Println(a, b) } ``` 注意:和引數不同,有幾個返回值就寫幾個返回值型別,不能簡寫。 Go語言還提供了另一種函式返回的方式:命名返回值。 顧名思義,我們通過給返回值進行命名,使用空`return`語句,這樣會直接返回已命名的返回值。如上例的`sumAndDiff`函式可以寫為: ```go func sumAndDiff(x, y int) (sum int, diff int) {//提前命名返回值 sum = x + y diff = x - y //返回值在函式中被初始化 return //返回值已經初始化了,不需要再在return語句中寫變量了 } ``` 下面總結一下函式的使用: ```go func functionName(input1, input11 type1, input2 type2 ...) (type1, type11, type2 ...){ //函式體 return value1, value11, value2 ... } ``` 或者命名返回值 ```go func functionName(input1, input11 type1, input2 type2 ...) (output1 type1, output11 type11, output2 type2 ...){ //函式體 output1 = ... output11 = ... output2 = ... ... return } ``` # 6. 匯出名 前面我們已經使用了`import`**匯入**功能,比如`improt "fmt"`,該行程式碼可以讓我們在本包中使用其他包裡的函式。 那麼我們如何讓其他包能夠使用到本包的方法或變數呢?答案是:將方法或變數**匯出**。 在Go語言中,如果一個名字以大寫字母開頭,那麼它就是已匯出的,這意味著別的包可以使用它。(相當於Java中的`public`的作用) 比如我們常用的列印函式`fmt.Println(...)`,可以看到`Println()`的首字母是大寫的,所以我們能夠匯入`fmt`包後使用該方法。 # 7. 流程控制語句 ## 7.1. if語句 if語句是條件判斷語句,用來判斷是否滿足某種條件,如果滿足,則執行某段程式碼;如果不滿足,則不執行。 ```go if ... { //程式碼 } else if ... { //程式碼 } else { //程式碼 } ``` 注意格式:條件判斷語句**不需要**使用小括號`()`。 下面是幾個例子: ```go if a > 0 {//如果滿足a>0,則列印Hello, World fmt.Println("Hello, World") } ``` ```go if a > 0 {//如果滿足a>0,則列印 Hello, World fmt.Println("Hello, World!") } else {//否則(即不滿足a>0),則列印 你好,世界! fmt.Println("你好,世界!") } ``` ```go if a > 5 {//如果滿足a>5,則列印 Hello, World fmt.Println("Hello, World!") } else if a <= 5 && a > 0 {//如