【Go】雜七雜八GoLang
阿新 • • 發佈:2021-08-10
雜
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
的方式。這時會將...
- 接收器和方法: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整數。
- switch:
- 字串:字串是不可變的,是不定長位元組,不能對字串中某個字元單獨賦值,不支援下標操作。
- 指標:不支援指標運算。
- 平行賦值:等號左邊和右邊含有多個表示式。
- 高階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生效
-
先在DialURL中引數options中設定DialClientname。
-
DialClientName返回了一個DialOption,這個DialOption設定了clientname。
-
DialOption這個struct包了一個func,在func裡面對引數do進行設定。
func DialClientName(name string) DialOption { return DialOption{func(do *dialOptions) { do.clientName = name }} }
-
-
DialURL中設定passwd, address等,然後呼叫Dial
-
Dial呼叫DialContext
-
Dial只是呼叫了DialContext,傳入context.Background作為Context。
func Dial(network, address string, options ...DialOption) (Conn, error) { return DialContext(context.Background(), network, address, options...) }
-
-
DialContext
- 設定dialOptions型別do中Timeout、Keepalive、tlsHandshakeTiemout等引數。
- 呼叫options中的f func,設定do的clientname欄位。
- 通過do的dialContext獲得netConn,獲得&conn的c。
- 當
do.clientname!=""
才呼叫c.do進行設定CLIENTNAME。
- 當clientname為空字串時,其實是不會進行設定clientname的。
Go程式載入流程
- 初始化流程,執行main.main()之前,Go載入程式會先對整個程式的包進行初始化。
- 包初始化從main()引用的包開始,逐級查詢,最終生成一個包引用的有向無環圖。
- 先初始化常量 const...
- 然後初始化全域性變數 var...
- 執行包的init()
go記憶體管理機制
golang中不存在野指標
- go語言的自動記憶體管理機制使得只要還有一個指標引用一個變數,那這個變數就會在記憶體中得以保留。
- go語言中變數是分配在棧中還是在堆中也是不能確定的,棧中的變數可能會逃逸到堆,堆中的變數也可能因為編譯優化而在棧中分配,這都是由go語言管理的。
記憶體洩漏
- 在Go語言裡,我們檢測記憶體洩漏主要依靠的是go裡面的pprof包。
- 除此之外,我們還可以使用瀏覽器來檢視系統的實時記憶體資訊(包括CPU、goroutine等的資訊)。