Go 語言學習筆記


1. go沒有static關鍵字

面向對象編程中,盡量對函數進行封裝,對於沒有函數變量的對象,使用static關鍵字尤其方便。
go中沒有static關鍵字,必須每次new一個出來。

type Handler struct {
}

func NewHandler() *Handler {
	h := &Handler{}
	return h
}

func (*Handler) Method_1 (){
	
}

func (*Handler) Method_2 () {
	
}

2. go沒有while; do...while循環

go語言里面的for循環比較靈活

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
	}
}

3. go每個協程都必須捕獲panic

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))
}

4. go中巧用defer函數逆序執行

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")
}

5. go中巧用interface

interface類似C/C++中的void*類型,可以將任何類型轉為interface類型。
不同的是, interface可以確定保存的是那種類型的數據. 使用 v.(type)

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")
		}
	}
}

6. go注意大小寫

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)
		}
	}
}

7. go中變量申明后都有默認值

在go語言中,任何類型在聲明后沒有賦值的情況下,都對應一個零值。

  • 整形如int8、byte、int16、uint、uintprt等,默認值為0
  • 浮點類型如float32、float64,默認值為0
  • 布爾類型bool的默認值為false
  • 復數類型如complex64、complex128,默認值為0+0i
  • 字符串string的默認值為""
  • 錯誤類型error的默認值為nil
  • 對於一些復合類型,如指針、切片、字典、通道、接口,默認值為nil。而數組的默認值要根據其數據類型來確定。例如:var a [4]int,其默認值為[0 0 0 0]

8. go中可以使用fmt構造一個error類型返回

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())
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM