1. 程式人生 > 其它 >【Go】雜七雜八GoLang

【Go】雜七雜八GoLang

assert

  • Every assertion function also takes an optional string message as the final argument, allowing custom error messages to be appended to the message the assertion method outputs.

  • func TestSomething(t *testing.T) {
      var a string = "Hello"
      var b string = "Hello"
      assert.Equal(t, a, b, "The two words should be the same.")
    }
    // assert many times
    func TestSomething(t *testing.T) {
      assert := assert.New(t)
    
      var a string = "Hello"
      var b string = "Hello"
    
      assert.Equal(a, b, "The two words should be the same.")
    }
    

validator

  • required :必填
  • email:驗證字串是email格式;例:“email”
  • url:這將驗證字串值包含有效的網址;例:“url”
  • max:字串最大長度;例:“max=20”
  • min:字串最小長度;例:“min=6”
  • excludesall:不能包含特殊字元;例:“excludesall=0x2C”//注意這裡用十六進位制表示。
  • len:字元長度必須等於n,或者陣列、切片、map的len值為n,即包含的專案數;例:“len=6”
  • eq:數字等於n,或者或者陣列、切片、map的len值為n,即包含的專案數;例:“eq=6”
  • ne:數字不等於n,或者或者陣列、切片、map的len值不等於為n,即包含的專案數不為n,其和eq相反;例:“ne=6”
  • gt:數字大於n,或者或者陣列、切片、map的len值大於n,即包含的專案數大於n;例:“gt=6”
  • gte:數字大於或等於n,或者或者陣列、切片、map的len值大於或等於n,即包含的專案數大於或等於n;例:“gte=6”
  • lt:數字小於n,或者或者陣列、切片、map的len值小於n,即包含的專案數小於n;例:“lt=6”
  • lte:數字小於或等於n,或者或者陣列、切片、map的len值小於或等於n,即包含的專案數小於或等於n;例:“lte=6”

函式

  • variadic:有時候引數過多,或者想要讓函式處理任意多個的引數,可以在函式定義語句的引數部分使用ARGS...TYPE的方式。這時會將...
    代表的引數全部儲存到一個名為ARGS的slice中,注意這些引數的資料型別都是TYPE。
  • 接收器和方法:func和方法名之間有一個引數,這個引數為方法的receiver,於是定義的這個方法和接收者繫結在了一起。類似於Java中的類內的成員函式。

goroutine

  • goroutine是Go中輕量級執行緒實現,由Go執行時(runtime)管理。
  • 關鍵字 go 建立一個goroutine。
  • 所有的goroutine在main()函式結束時會一同結束。

閉包

  • Go中閉包是引用了自由變數的函式,被引用的自由變數和函式一同存在,即使已經離開了自由變數的環境也不會被釋放或者刪除,在閉包中可以繼續使用這個自由變數。
  • 閉包會使得函式中的變數都被儲存在記憶體中,記憶體消耗很大。

Context

  • 用於設定截止日期、同步訊號,傳遞請求相關值的結構體。

  • // 需要實現這4個方法
    type Context interface {
    	Deadline() (deadline time.Time, ok bool)
    	Done() <-chan struct{}
    	Err() error
    	Value(key interface{}) interface{}
    }
    

reflect

  • reflect.TypeOf():返回一個表示著唯一介面引數值的動態型別的reflect.Type值
  • reflect.Type型別物件有成員函式
    • Name(): 型別名
    • Kind():種類

interface{ }型別

  • interface{}型別,空介面,是沒有方法的介面,所有型別都實現了空介面。

廢棄方法api

  • 在方法上加上註釋Deprecated

cap

  • arry:返回陣列的元素個數
  • slice:返回slice的最大容量
  • channel:返回channel的buffer容量

語法

  • 取反:用^或者!,go不支援~符號。
  • import:import後面跟的是包路徑,而不是包名。
    • 同個目錄下可以有多個.go檔案,但是隻能有一個包。
    • 使用第三方庫時,先將原始碼編譯.a檔案放到臨時目錄下,然後去連結這個.a檔案,而不是go install安裝的那個.a檔案;
    • 使用標準庫時,直接連結.a檔案,即使修改了原始碼,也不會從新編譯原始碼;
    • 不管使用的是標準庫還是第三方庫,原始碼都是必須存在的,即使使用的是.a檔案。
  • 常量:go語言常量要是編譯時就能確定的資料
    • errors.New("xxx") 要等到執行時才能確定,所以它不能是const。
    • 儲存在常量中的資料型別只可以是布林型、數字型(int, float, complex)和string。
  • 迴圈語句
    • switch
      • 宣告語句和表示式語句都是可選的。(可以不設定swicth後的條件表示式,和if...else同個效果)
      • 不需要break手動退出case。
      • 條件表示式限制為常量or整數。
  • 字串:字串是不可變的,是不定長位元組,不能對字串中某個字元單獨賦值,不支援下標操作。
  • 指標:不支援指標運算。
  • 平行賦值:等號左邊和右邊含有多個表示式。
  • 高階break:可以選擇中斷哪個迴圈。
  • main
    • main函式不能帶引數
    • main函式不能定義返回值
    • main函式所在的包必須是main包
    • main函式中可以使用flag包來獲取和解析命令列引數

struct、interface

  • go裡沒有類這個概念
  • interface中只能定義函式,不能定義變數。
  • struct裡只能定義變數。
  • struct對interface的實現是隱式的,只要實現了interface裡的函式,則相當於實現了interface,效果有點像成員方法。

go框架

GoMock

  • interface可以通過GoMock框架打樁。

redigo

redis.Conn連結物件相關方法

  • conn.Do() :Do傳送一條命令到redis伺服器端執行並返回結果
  • conn.Send(): Send傳送命令到快取
  • conn.Flush(): Flush傳送命令到服務端執行
  • conn.Receive(): Receive方法獲取命令執行結果
  • conn.Close(): 關閉連結

Pool連線池獲取conn物件

  • pool封裝dial實現連線池。

  • conn := pool.Get() //get方法獲取conn連結物件
    
  • redis.Dial():獲取conn

DialOption生效

  1. 先在DialURL中引數options中設定DialClientname。

  2. DialClientName返回了一個DialOption,這個DialOption設定了clientname。

    • DialOption這個struct包了一個func,在func裡面對引數do進行設定。

    func DialClientName(name string) DialOption {
    	return DialOption{func(do *dialOptions) {
    		do.clientName = name
    	}}
    }
    
  3. DialURL中設定passwd, address等,然後呼叫Dial

  4. Dial呼叫DialContext

    1. Dial只是呼叫了DialContext,傳入context.Background作為Context。

    func Dial(network, address string, options ...DialOption) (Conn, error) {
    	return DialContext(context.Background(), network, address, options...)
    }
    
  5. DialContext

    1. 設定dialOptions型別do中Timeout、Keepalive、tlsHandshakeTiemout等引數。
    2. 呼叫options中的f func,設定do的clientname欄位。
    3. 通過do的dialContext獲得netConn,獲得&conn的c。
    4. do.clientname!=""才呼叫c.do進行設定CLIENTNAME。
  • 當clientname為空字串時,其實是不會進行設定clientname的。

Go程式載入流程

  • 初始化流程,執行main.main()之前,Go載入程式會先對整個程式的包進行初始化。
    1. 包初始化從main()引用的包開始,逐級查詢,最終生成一個包引用的有向無環圖。
    2. 先初始化常量 const...
    3. 然後初始化全域性變數 var...
    4. 執行包的init()

go記憶體管理機制

golang中不存在野指標

  • go語言的自動記憶體管理機制使得只要還有一個指標引用一個變數,那這個變數就會在記憶體中得以保留。
  • go語言中變數是分配在棧中還是在堆中也是不能確定的,棧中的變數可能會逃逸到堆,堆中的變數也可能因為編譯優化而在棧中分配,這都是由go語言管理的。

記憶體洩漏

  • 在Go語言裡,我們檢測記憶體洩漏主要依靠的是go裡面的pprof包
  • 除此之外,我們還可以使用瀏覽器來檢視系統的實時記憶體資訊(包括CPU、goroutine等的資訊)。