面向對象編程中,儘可能對函數進行封裝,對於沒有函數變量的對象,使用static關鍵字尤爲方便。
go中沒有static關鍵字,必須每次new一個出來。編程
type Handler struct { } func NewHandler() *Handler { h := &Handler{} return h } func (*Handler) Method_1 (){ } func (*Handler) Method_2 () { }
go語言裏面的for循環比較靈活json
func main(){ for { fmt.Printf("while true\n") break } for i:=0; i < 5; i = i + 1 { fmt.Printf("while data:%d\n", i) } i := 0 for i < 5 { fmt.Printf("while ok:%d\n", i) i = i + 1 } }
go中每一個協程都必須捕獲panic, 不然任何一個協程問題,都會致使整個程序dump掉。數組
func no_panic_get(a, b int){ /* //每一個go協程都必須捕獲panic, 不然整個程序都會panic defer func() { if r := recover(); r != nil { fmt.Printf("no_panic_get, err:%v\n", r) } }() */ c := a / b fmt.Printf("no_panic_get res:%v\n", c) } func main(){ defer func() { if r := recover(); r != nil { fmt.Printf("exec failed, err:%v\n", r) } else { fmt.Printf("exec success\n") } }() go no_panic_get(1,0) //no_panic_get沒有捕獲panic, 程序直接panic崩潰 time.Sleep(time.Duration(5 * time.Second)) }
defer函數,是在函數最後執行的。
屬於先申明,後執行原則;多個defer,申明時入棧,出棧時執行,也就是逆序執行。
只要第一個申明的defer,做爲最後一個捕獲panic程序執行就能夠。函數
func main(){ defer func() { fmt.Printf("defer func1\n") } () defer func() { fmt.Printf("defer func2\n") } () fmt.Printf("main func\n") }
interface相似C/C++中的void*類型,能夠將任何類型轉爲interface類型。
不一樣的是, interface能夠肯定保存的是那種類型的數據. 使用 v.(type)ui
type A struct { age int sex string } type B struct { peer []string name string } func main(){ aData := &A{age:19} bData := &B{[]string{"zhangsan", "lisi"},"wang"} ctx := make(map[string]interface{}) //容器 ctx["1"] = aData ctx["2"] = bData for _, v := range ctx { switch v.(type) { case *A: fmt.Printf("type A %v\n", v) case *B: fmt.Printf("type B %v\n", v) default: fmt.Printf("type unkown\n") } } }
go中大小寫區分訪問權限, 在定義函數,定義變量時須要注意。
小寫變量,不能被json序列化。
小寫函數,外部不能訪問。
go1.4 以前版本中, map[int]string, 由於key是int不能正確序列號。指針
type Stu struct { Age int Name string } func main(){ ctx := make(map[int]*Stu) ctx[1] = &Stu{12,"li"} //按照定義順序初始化 ctx[2] = &Stu{ Age:18} //初始化部分字段; 其餘字段默認值 jsonres, _ := json.Marshal(ctx) result := string(jsonres) fmt.Printf("%s\n", result) newctx := make(map[int]*Stu) if err := json.Unmarshal([]byte(result), &newctx); err == nil { //第二個參數須要是一個指針 for k, v := range newctx{ fmt.Printf("k:%v val:%v\n", k, v) } } }
在go語言中,任何類型在聲明後沒有賦值的狀況下,都對應一個零值。code
go語言函數是支持多返回值的,所以在寫go函數時,都會帶一個error類型返回值表示是否有錯誤。
可使用fmt構造一個error返回。協程
func getError() error { a := 1 b := 0 return fmt.Errorf("a/b is not vaild, a:%d b:%d", a, b) } func main(){ fmt.Printf("err[%v]", getError()) }