1. 程式人生 > >Golang快速入門

Golang快速入門

Go語言簡介:

Golang 簡稱 Go,是一個開源的程式語言,Go是從2007年末由 Robert Griesemer, Rob Pike, Ken Thompson主持開發,後來還加入了Ian Lance Taylor, Russ Cox等人,並最終於2009年11月開源,在2012年早些時候釋出了Go 1穩定版本。

1.Go語言用途:

Go 語言被設計成一門應用於搭載 Web 伺服器,儲存叢集或類似用途的巨型中央伺服器的系統程式語言。
Go 語言在用於高效能分散式系統開發中,無疑比大多數其它語言有著更高的開發效率。此外,它提供了海量並行的支援,這對於遊戲服務端的開發而言也是不錯的選擇。

2.Go語言開源專案:

有著媲美C語言的效能和Python的開發效率,被稱為21世紀的C語言。目前使用Go語言開發的一些優秀的開源專案有:Dockeretcdkubernetes等。

3.Go語言特點:

  • 優點:

    • 簡潔、快速、安全
    • 支援併發程式設計
    • 自動垃圾回收
    • 編譯迅速
    • 便捷部署:go最終生成的是一個 可執行檔案,不管你的程式依賴多少庫,都會被打包進行,生成一個可執行檔案,所以相比java龐大的jar庫來說,他的部署非常方便,執行執行這個可執行檔案就好了。
  • 缺點:

    • 錯誤處理比較繁瑣,需要寫很多 err 判斷

Go開發環境配置:

訪問 Golang官網

,下載指定平臺的安裝包,目前支援WindowsMacOS XLinuxFreeBSD 四個平臺,這裡我們以Windows為例:

1.*Windows下的安裝:*

  • 資源地址:
    可以到這裡下載安裝包:Golang中國 或者 官網下載

  • 檢查版本:
    直接開啟cmd命令列,輸入一下指令查詢安裝Go的版本:

    C:\Users\Administrator>go version
    go version go1.8.3 windows/amd64

2.Linux下的安裝:

  • 解壓到/usr/local目錄:tar -C /usr/local -xzf go1.8.3.linux-amd64.tar.gz
  • /usr/local/go/bin目錄新增到Path環境變數中:export PATH=$PATH:/usr/local/go/bin

3.Hello World:

  • Tour編輯器:
    假如只是前期的語法學習,可以考慮先不安裝開發環境,可以直接在 Golang官網 上的網頁內嵌 Tour編輯器 中編寫程式碼和執行:
    在編輯器中編寫如下程式碼:

    package main
    
    import "fmt"
    
    func main() {
        fmt.Println("Hello world!")
    }

    執行結果:

  • 本地執行:
    也可以在本地建立一個hello.go檔案,內容與上述一致,然後在命令列定位到建立.go檔案的目錄下,執行go run (.go檔名)

    E:\Go\Projects>go run hello.go
    Hello world!

    此過程會將.go原始碼編譯成二進位制檔案,但是編譯結果不會儲存到本地,可以go build實現此過程,編譯結果hello.exe會儲存到本地,可以直接在命令列執行:

    E:\Go\Projects>hello.exe
    Hello world!
  • 原始碼解析:

    • package:是一個關鍵字,定義一個包,和Java中的Package一樣,用於模組化程式設計;
    • import:也是一個關鍵字,用於引入包,與Java的import一樣,引入包之後可以使用其中的功能;
    • fmt:Go語言的一個自帶功能包;
    • main():主函式,也是程式執行的入口;
    • fmt.Println:用於輸出一段字串。

    不難發現Go語言與Java的關鍵字、函式和包等很相似,但是,Go語言不需要以 ; (分號)符號結尾,一行代表一個語句結束。

Go基本語法:

1.基本資料型別:

數值型別 說明
bool 布林
string 字元
int,int8,int16,int32,int64 int長度與平臺相關
uint,uint8,uint16,uint32,uint64 uint長度與平臺相關
uintptr 同指針,32位平臺為4位元組,64位八位元組
byte 等價於uint8
rune 等價於uint32,單個unicode字元
float32,float64
complex64,complex128 複數型別, value = 3.2+12i

2.數值定義:

Go語言最獨特的就是:宣告變數或者常量時,型別表示寫在變數或者常量名稱之後。

  • 常量:

    • 顯式定義
    const a int = 1
    • 隱式定義
    const a = 1

    可以進行多個相同或不同型別的宣告:

    const a, b, c = 1, false, "str" //多重賦值
  • 變數:

    var s string = "hehe"

    聲明後若不賦值,使用預設值:

    int a

    假如輸出a結果,則為int預設值0。還可以同時對多個相同或不同型別的變數進行宣告:

    var e, f = 123, "hello"

    也有一種簡化的宣告方式,不需顯示宣告變數型別也省去了var,變數的型別由go根據值推匯出來:

    s := "hehe"

有興趣的還可以瞭解一下值型別引用型別的區別。

3.操作符:

  • 賦值: =,:=
  • 數值運算: +(相加),-(相減),*(相乘),/(相除),%(求餘),++(自增),--(自減)
  • 比較運算: >,<,==,>=,<=,!=
  • 邏輯運算: &&,||,!
  • 位執行: >>,<<,^,&(與),|(或),^x(取反)
  • 其他: &(變數儲存地址),*(指標變數)

其中有兩個比較特殊的操作符:

特殊操作符 說明
:= 無需指定型別即可賦值:i, j := true, "hello"
_ 空白識別符號,可以賦任意值的空物件:_ = "string"

空白識別符號 _ 也被用於拋棄值,如值 5 在:_, b = 5, 7 中被拋棄。
_ 實際上是一個只寫變數,你不能得到它的值。這樣做是因為 Go 語言中你必須使用所有被宣告的變數,但有時你並不需要使用從一個函式得到的所有返回值。

4.大小寫標記訪問許可權:

在go中不能隨便使用大小寫的問題,是因為大小寫具有特殊意義,在go中,大寫字母開頭的變數或者函式等是public的,可以被其他包訪問;小寫的則是private的,不能被其他包訪問到。這樣就省去了public和private宣告的煩惱,使程式碼變的更簡潔。

5.關鍵字:

關鍵字 作用
package 程式碼所屬包
import 匯入依賴包,不能匯入不使用的包
main 主函式入口,無引數無返回值,命令列引數儲存在os.Args中
func 函式宣告
go 開啟協程(併發核心)
map 字典型別, map[string]bool
delete 專用來刪除字典中的元素
chan 通道,協程通訊核心
select 同時讀取多個chan的資訊
close 用來關閉通道
make 用來建立chan或map
type 型別定義,定義任意需要的型別
struct C中的結構體,但可以定義方法以實現類功能
interface 介面型別,用來定義介面
new 新建物件, 並獲得它的指標
range 類似python的range,配合for遍歷列表、陣列或map的元素
defer 自動關閉資源,退出程式碼體(一般是函式)時執行
error error介面,只要實現Error()string方法就是一個error介面
panic 丟擲異常,如果不用recover捕獲則會終止程式
recover 捕獲panic異常,防止程式終止,與recover結合

6.註釋:

Go 程式的程式碼註釋與 C++ 保持一致,主持:塊註釋行註釋

  • 塊註釋:

    /*
    塊註釋
    */
  • 行註釋:

    // 行註釋

7.流程控制:

  • 條件:

    條件語句 說明
    if if 語句 由一個布林表示式後緊跟一個或多個語句組成。
    if…else if 語句 後可以使用可選的 else 語句, else 語句中的表示式在布林表示式為 false 時執行。
    if 巢狀 你可以在 if 或 else if 語句中嵌入一個或多個 if 或 else if 語句。
    switch switch 語句用於基於不同條件執行不同動作。
    select select 語句類似於 switch 語句,但是select會隨機執行一個可執行的case。如果沒有case可執行,它將阻塞,直到有case可執行。
    • if

      if i>0 {
      //條件執行內容
      }

      相比於其他語言,Go語言的條件判斷語句不需要小括號

      // 特殊用法, 判斷語句中可以初始化變數
      if i:=4;i>0{
      fmt.Println("i = ",i)
      }
    • switch,case

      switch i {
      case 0:
      // ...
      case 1:
      // ...
      default:
      // ...
      }

      Go語言的 switch 不需要 break 來跳出一個 case

    • select
      可以看做是專用於通訊的switch語句,每一個case必須是一個通訊操作,要麼是傳送要麼是接收。select執行邏輯:隨機執行一個可執行的case。如果沒有case可執行,它將阻塞,直到有case可執行。一個預設的子句應該總是可執行的。

      select {
      case communication clause  :
         statement(s);      
      case communication clause  :
         statement(s); 
      /* 你可以定義任意數量的 case */
      default : /* 可選 */
         statement(s);
      }

      執行select的語法大致如下:

      • 每個 case 都必須是一個通訊
      • channel 表示式都會被求值
      • 所有被髮送的表示式都會被求值
      • 如果任意某個通訊可以進行,它就執行;其他被忽略。
      • 如果有多個 case 都可以執行,select 會隨機公平地選出一個執行。其他不會執行。
      • 否則:
        1.如果有 default 子句,則執行該語句。
        2.如果沒有 default 字句,select 將阻塞,直到某個通訊可以執行;Go不會重新對channel或值進行求值。
  • 迴圈:

    迴圈語句 說明
    for 重複執行語句塊
    for巢狀 在 for 迴圈中巢狀一個或多個 for 迴圈

    Go語言中的for迴圈與Java、C#等的區別就是三個由 ;(分號)分開的組成部分不需要小括號括起來:

    for i := 0; i < 10; i++ {
    sum += i
    }

    Go語言中沒有其他語言中while的用法,for 在Go語言中可以當做 while 來用:

    sum := 1
    //迴圈條件
    for sum < 1000 {
    sum += sum
    }
    //死迴圈
    for {// 無退出條件,變成死迴圈
    }
  • 其他:
    在Go語言中,同樣可以使用breakcontinuegoto來控制流程:

    控制語句 說明
    break 經常用於中斷當前 for 迴圈或跳出 switch 語句
    continue 跳過當前迴圈的剩餘語句,然後繼續進行下一輪迴圈
    goto 將控制轉移到被標記的語句。

    例如goto,需要用一個文字來標誌某個語句(寫在該語句前面):

    goto label
    ..
    .
    label: statement

    label 就是用來標誌的文字,statement 是一個普通的Go語句,goto label執行之後,程式將調到 statement 然後順序往下執行。

8.函式:

Go語言中定義一個函式的格式如下:

func 方法名稱([傳入引數表]) [返回結果資料型別]{
    //函式體
}

上面使用[]符號括起來的部分表示 非必須 的,可根據使用情況決定是否可以不寫,例如無需傳入引數時,傳入引數列表可以省略。注意:傳入的引數列表中形式引數定義的格式也是:變數名在前,變數型別在後

  • 普通用法:

    package main
    
    import "fmt"
    
    func main(){
        PrintSth(1,2)
        sum := 0
        sum = mSum(10,20)
        fmt.Println("sum = ",sum)
    }
    
    func PrintSth(x,y int){
        fmt.Println("x = ",x,";y = ",y)
    }
    
    func mSum(x,y int) int{
        return x+y
    }
  • 返回多個值:
    例如定義一個值互換的方法:

    //定義函式
    func swap(x, y string) (string, string) {
    return y, x
    }
    //呼叫函式
    a,b := swap("a","b")
  • 函式作為值:
    定義函式的時候,也可以將函式宣告為一個函式變數,呼叫的時候用函式變數替換函式真是名稱來呼叫即可:

    /* 宣告函式變數 */
    getSquare := func(x float64) float64 {
        return x*x
    }
    
    /* 使用函式 */
    fmt.Println(getSquare(3))
  • 閉包:
    閉包,是匿名函式(一個“內聯”語句或表示式)的一種宣告方式,好處就是可以直接使用函式內的變數不必宣告:

    //沒呼叫一次getSequence,i就自增1
    func getSequence() func() int {
    i:=0
    return func() int {
       i+=1
       return i
    }
    }

    函式的返回結果是另一個函式。

  • 方法:
    與函式略有不同,方法宣告時會指定其所附的是命名型別或結構型別的一個值或者是一個指標,所有給定型別的方法屬於該型別的方法集。例如:

    //定義結構體
    type Circle struct {
    radius float64
    }
    //此屬於 Circle 型別物件中的方法
    func (c Circle) getArea() float64 {
    //c.radius 即為 Circle 型別物件中的屬性
    return 3.14 * c.radius * c.radius
    }
    //呼叫
    main(){
    var c Circle
    c.radius = 1
    fmt.Println("Area of c = ", c.getArea())
    }

9.指標:

  • 指標變數:
    一個 指標變數 可以指向任何一個值的記憶體地址,使用指標前需要宣告,宣告格式如下:

    var var_name *var-type

    var_name 是變數名,var-type 是指標型別,例如:

    var ip *int        // 此指標只能指向整型
  • 使用步驟:
    建立指標變數,為指標賦值(如:指向變數),輸出結果:

    var a int = 1
    //建立指標變數
    var ptr *int
    //指標賦值(指向變數a的地址)
    ptr = &a
    /* 指標變數的儲存地址 */
    fmt.Printf("ptr 變數儲存的指標地址: %x\n", ptr )
    /* 使用指標訪問值 */
    fmt.Printf("*ptr 變數的值: %d\n", *ptr )
  • 取址符:
    Go語言中,使用 &取址符,假如放在變數前可以返回相應變數的記憶體地址:

    var a int = 1
    fmt.Printf("變數的地址: %x\n", &a  )

    輸出結果:

    變數的地址: c0420382a0
  • 空指標:
    Go語言中的空指標是 nil ,表示沒有分配到任何變數,判斷指標是否為空指標:

    //宣告指標,不賦值
    var ptr *int
    if ptr == nil{
    //條件執行塊
    }

10.結構體:

以關鍵字 typestruct 來一起宣告一個結構體,格式如下:

type structure_variable_type struct{
    member menberType
    member menberType
    ...
}

其中 structure_variable_type 是當前定義結構體的名稱,建立結構體操作:

variable_name := structure_variable_type(value1,value2,...)

例如:

//定義
type Info struct{
    id int
    name string
}
//宣告
var mInfo Info
//賦值
mInfo.id = 1
mInfo.name = "linsh"

11.包的使用:

每個Go程式都是由包組成的,其中程式執行入口包為 main ,通常包名與匯入目錄路徑最後一級目錄名稱一致。例如:匯入“math、rand”包,這個包必然是以 package rand 語句開始的。

  • 匯入包:
    import 關鍵字來實現包的匯入,有兩種格式:

    • 多個匯入語句:

      import "fmt"
      import "math"
    • “打包”匯入:

      import (
      "fmt"
      "math"
      )

    使用第二種方式匯入包更為方便。

  • 匯出命名:
    在Go程式設計中,某個包中 使用首字母大寫的名稱定義的屬性或者方法可以被匯入了此包的指令碼呼叫,相當於是開放了訪問許可權,例如:這裡我們定義了一個 ··Test·· 包,然後再 main 包中引入此包並呼叫其匯出方法:

    package Test
    
    func SetName(_name string){
    
    }
    
    func setName(_name string){
    
    }

    main 中先 import Test,然後只能呼叫 SetName 函式而不能呼叫 setname

參考資料: