1. 程式人生 > >golang基礎之初識

golang基礎之初識

例如 速度 最大 轉發 其他 python 所有 delete cap

golang 簡介

很久以前,有一個IT公司,這公司有個傳統,允許員工擁有20%自由時間來開發實驗性項目。在2007的某一天,公司的幾個大牛,正在用c++開發一些比較繁瑣但是核心的工作,主要包括龐大的分布式集群,大牛覺得很鬧心,後來c++委員會來他們公司演講,說c++將要添加大概35種新特性。這幾個大牛的其中一個人,名為:Rob Pike,聽後心中一萬個xxx飄過,“c++特性還不夠多嗎?簡化c++應該更有成就感吧”。於是乎,Rob Pike和其他幾個大牛討論了一下,怎麽解決這個問題,過了一會,Rob Pike說要不我們自己搞個語言吧,名字叫“go”,非常簡短,容易拼寫。其他幾位大牛就說好啊,然後他們找了塊白板,在上面寫下希望能有哪些功能(詳見文尾)。接下來的時間裏,大牛們開心的討論設計這門語言的特性,經過漫長的歲月,他們決定,以c語言為原型,以及借鑒其他語言的一些特性,來解放程序員,解放自己,然後在2009年,go語言誕生。

思想

Less can be more 大道至簡,小而蘊真 讓事情變得復雜很容易,讓事情變得簡單才難 深刻的工程文化

優點

  • 自帶gc。
  • 靜態編譯,編譯好後,扔服務器直接運行。
  • 簡單的思想,沒有繼承,多態,類等。
  • 豐富的庫和詳細的開發文檔。
  • 語法層支持並發,和擁有同步並發的channel類型,使並發開發變得非常方便。
  • 簡潔的語法,提高開發效率,同時提高代碼的閱讀性和可維護性。
  • 超級簡單的交叉編譯,僅需更改環境變量。(花了我兩天時間編譯一個imagemagick到arm平臺)
  • 內含完善、全面的軟件工程工具。Go語言自帶的命令和工具相當地強大。通過它們,我們可以很輕松地完成
  • Go語言程序的獲取、編譯、測試、安裝、運行、運行分析等一系列工作,這幾乎涉及了開發和維護一個軟件的所有環節。

Go 語言是谷歌 2009 年首次推出並在 2012 年正式發布的一種全新的編程語言,可以在不損失應用程序性能的情況下降低代碼的復雜性。谷歌首席軟件工程師羅布派克(Rob Pike)說:我們之所以開發 Go,是因為過去10多年間軟件開發的難度令人沮喪。Google 對 Go 寄予厚望,其設計是讓軟件充分發揮多核心處理器同步多工的優點,並可解決面向對象程序設計的麻煩。它具有現代的程序語言特色,如垃圾回收,幫助開發者處理瑣碎但重要的內存管理問題。Go 的速度也非常快,幾乎和 C 或 C++ 程序一樣快,且能夠快速開發應用程序。

Go語言的主要特征:

  • 自動立即回收。
  • 更豐富的內置類型。
  • 函數多返回值。
  • 錯誤處理。
  • 匿名函數和閉包。
  • 類型和接口。
  • 並發編程。
  • 反射。
  • 語言交互性。

Golang文件名:

    所有的go源碼都是以 ".go" 結尾。

Go語言命名:

1.Go的函數、變量、常量、自定義類型、包(package)的命名方式遵循以下規則:

    1)首字符可以是任意的Unicode字符或者下劃線
    2)剩余字符可以是Unicode字符、下劃線、數字
    3)字符長度不限

2.Go只有25個關鍵字

    break        default      func         interface    select
    case         defer        go           map          struct
    chan         else         goto         package      switch
    const        fallthrough  if           range        type
    continue     for          import       return       var

3.Go還有37個保留字

    Constants:    true  false  iota  nil

    Types:    int  int8  int16  int32  int64  
              uint  uint8  uint16  uint32  uint64  uintptr
              float32  float64  complex128  complex64
              bool  byte  rune  string  error

    Functions:   make  len  cap  new  append  copy  close  delete
                 complex  real  imag
                 panic  recover

4.可見性:

    1)聲明在函數內部,是函數的本地值,類似private
    2)聲明在函數外部,是對當前包可見(包內所有.go文件都可見)的全局值,類似protect
    3)聲明在函數外部且首字母大寫是所有包可見的全局值,類似public

Go語言聲明:

有四種主要聲明方式:

    var(聲明變量), const(聲明常量), type(聲明類型) ,func(聲明函數)。

Go的程序是保存在多個.go文件中,文件的第一行就是package XXX聲明,用來說明該文件屬於哪個包(package),package聲明下來就是import聲明,再下來是類型,變量,常量,函數的聲明。

Go項目構建及編譯

一個Go工程中主要包含以下三個目錄:

src:源代碼文件
pkg:包文件
bin:相關bin文件

1: 建立工程文件夾 goproject
2: 在工程文件夾中建立src,pkg,bin文件夾
3: 在GOPATH中添加projiect路徑 例 e:/goproject
4: 如工程中有自己的包examplepackage,那在src文件夾下建立以包名命名的文件夾 例 examplepackage
5:在src文件夾下編寫主程序代碼代碼 goproject.go
6:在examplepackage文件夾中編寫 examplepackage.go 和 包測試文件 examplepackage_test.go
7:編譯調試包

go build examplepackage
go test examplepackage
go install examplepackage

這時在pkg文件夾中可以發現會有一個相應的操作系統文件夾如windows_386z, 在這個文件夾中會有examplepackage文件夾,在該文件中有examplepackage.a文件
8:編譯主程序
go build goproject.go
成功後會生成goproject.exe文件

至此一個Go工程編輯成功。

1.建立工程文件夾 go
$ pwd
/Users/***/Desktop/go
2: 在工程文件夾中建立src,pkg,bin文件夾
$ ls
bin     conf    pkg     src
3: 在GOPATH中添加projiect路徑
$ go env
GOPATH="/Users/liupengjie/Desktop/go"
4: 那在src文件夾下建立以自己的包 example 文件夾
$ cd src/
$ mkdir example
5:在src文件夾下編寫主程序代碼代碼 goproject.go
6:在example文件夾中編寫 example.go 和 包測試文件 example_test.go
    example.go 寫入如下代碼:
    
    package example

    func add(a, b int) int {
        return a + b
    }

    func sub(a, b int) int {
        return a - b
    }
    
    example_test.go 寫入如下代碼:
    
    package example

    import (
        "testing"
    )

    func TestAdd(t *testing.T) {
        r := add(2, 4)
        if r != 6 {
            t.Fatalf("add(2, 4) error, expect:%d, actual:%d", 6, r)
        }
        t.Logf("test add succ")
    }

7:編譯調試包
    $ go build example
    $ go test example
    ok      example 0.013s
    $ go install example
        
$ ls /Users/***/Desktop/go/pkg/
darwin_amd64
$ ls /Users/***/Desktop/go/pkg/darwin_amd64/
example.a   
8:編譯主程序
    oproject.go 寫入如下代碼:
    package main 

    import (
        "fmt"
    )

    func main(){
        fmt.Println("go project test")
    }
    
    $ go build goproject.go
    $ ls
    example     goproject.go    goproject
    
    成功後會生成goproject文件
    至此一個Go工程編輯成功。
    
    運行該文件:
    $ ./goproject
    go project test

go 編譯問題

golang的編譯使用命令 go build , go install;除非僅寫一個main函數,否則還是準備好目錄結構;
GOPATH=工程根目錄;其下應創建src,pkg,bin目錄,bin目錄中用於生成可執行文件,pkg目錄中用於生成.a文件;
golang中的import name,實際是到GOPATH中去尋找name.a, 使用時是該name.a的源碼中生命的package 名字;這個在前面已經介紹過了。

註意點:

  1. 系統編譯時 go install abc_name時,系統會到GOPATH的src目錄中尋找abc_name目錄,然後編譯其下的go文件;
  2. 同一個目錄中所有的go文件的package聲明必須相同,所以main方法要單獨放一個文件,否則在eclipse和liteide中都會報錯;
    編譯報錯如下:(假設test目錄中有個main.go 和mymath.go,其中main.go聲明package為main,mymath.go聲明packag 為test);
    $ go install test
    can‘t load package: package test: found packages main (main.go) and test (mymath.go) in /home/wanjm/go/src/test
    報錯說 不能加載package test(這是命令行的參數),因為發現了兩個package,分別時main.go 和 mymath.go;
  3. 對於main方法,只能在bin目錄下運行 go build path_tomain.go; 可以用-o參數指出輸出文件名;
  4. 可以添加參數 go build -gcflags "-N -l" ****,可以更好的便於gdb;詳細參見 http://golang.org/doc/gdb
  5. gdb全局變量主一點。 如有全局變量 a;則應寫為 p ‘main.a‘;註意但引號不可少;

golang內置類型和函數

  • 內置類型: (值類型)
bool
int(32 or 64), int8, int16, int32, int64
uint(32 or 64), uint8(byte), uint16, uint32, uint64
float32, float64
string
complex64, complex128
array    -- 固定長度的數組
  • 引用類型:(指針類型)
slice   -- 序列數組(最常用)
map     -- 映射
chan    -- 管道
  • 內置函數
    Go 語言擁有一些不需要進行導入操作就可以使用的內置函數。它們有時可以針對不同的類型進行操作,例如:len、cap 和 append,或必須用於系統級的操作,例如:panic。因此,它們需要直接獲得編譯器的支持。
append          -- 用來追加元素到數組、slice中,返回修改後的數組、slice
close           -- 主要用來關閉channel
delete          -- 從map中刪除key對應的value
panic           -- 停止常規的goroutine  (panic和recover:用來做錯誤處理)
recover         -- 允許程序定義goroutine的panic動作
imag            -- 返回complex的實部   (complex、real imag:用於創建和操作復數)
real            -- 返回complex的虛部
make            -- 用來分配內存,返回Type本身(只能應用於slice, map, channel)
new             -- 用來分配內存,主要用來分配值類型,比如int、struct。返回指向Type的指針
cap             -- capacity是容量的意思,用於返回某個類型的最大容量(只能用於切片和 map)
copy            -- 用於復制和連接slice,返回復制的數目
len             -- 來求長度,比如string、array、slice、map、channel ,返回長度
print、println   -- 底層打印函數,在部署環境中建議使用 fmt 包
  • 內置接口error
type error interface { //只要實現了Error()函數,返回值為String的都實現了err接口

        Error()    String

}

init函數

go語言中init函數用於包(package)的初始化,該函數是go語言的一個重要特性。

有下面的特征:

1 init函數是用於程序執行前做包的初始化的函數,比如初始化包裏的變量等

2 每個包可以擁有多個init函數

3 包的每個源文件也可以擁有多個init函數

4 同一個包中多個init函數的執行順序go語言沒有明確的定義(說明)

5 不同包的init函數按照包導入的依賴關系決定該初始化函數的執行順序

6 init函數不能被其他函數調用,而是在main函數執行之前,自動被調用

main函數

Go語言程序的默認入口函數(主函數):func main()
函數體用{}一對括號包裹。

func main(){
    //函數體
}

init函數和main函數的異同

相同點:
    兩個函數在定義時不能有任何的參數和返回值,且Go程序自動調用。
不同點:
    init可以應用於任意包中,且可以重復定義多個。
    main函數只能用於main包中,且只能定義一個。

兩個函數的執行順序:
對同一個go文件的init()調用順序是從上到下的。
對同一個package中不同文件是按文件名字符串比較“從小到大”順序調用各文件中的init()函數。
對於不同的package,如果不相互依賴的話,按照main包中"先import的後調用"的順序調用其包中的init(),如果package存在依賴,則先調用最早被依賴的package中的init(),最後調用main函數。

如果init函數中使用了println()或者print()你會發現在執行過程中這兩個不會按照你想象中的順序執行。這兩個函數官方只推薦在測試環境中使用,對於正式環境不要使用。

歡迎您關註程序員同行者訂閱號,程序員同行者是一個技術分享平臺,主要是運維自動化開發:linux、python、django、saltstack、redis、golang、docker、kubernetes、vue等經驗分享及經驗交流。

趁現在,關註我們

牛人並不可怕,可怕的是牛人比我們還努力!

如果您覺得不錯,請別忘了轉發、分享、點贊讓更多的人去學習, 您的舉手之勞,就是對小編最好的支持,非常感謝!

golang基礎之初識