golang基礎之初識

golang 簡介

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

思想

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

優勢

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

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

Go語言的主要特徵:

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

Golang文件名:

全部的go源碼都是以 ".go" 結尾。

Go語言命名:

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

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個保留字golang

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.可見性:redis

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

Go語言聲明:

有四種主要聲明方式:docker

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

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

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等經驗分享及經驗交流。

趁如今,關注咱們

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

若是您以爲不錯,請別忘了轉發、分享、點贊讓更多的人去學習, 您的舉手之勞,就是對小編最好的支持,很是感謝!

相關文章
相關標籤/搜索