天天看點

Go的異常退出場景1.因為數組/切片索引越界2.空指針調用3.過早關閉http響應體4.除以零5.向已經關閉的通道發送資訊6.重複關閉通道7.關閉未初始化的通道8.未初始化 map9.跨協程的“恐慌”處理10.sync計數為負值

go程式異常painc 退出的場景

引用書籍《Go語言程式設計之旅》

1.因為數組/切片索引越界

package main

import "fmt"

func main() {
	names := []string{
		"test",
		"test2",
	}
	name := names[len(names)]
	fmt.Println(name)

}
           
Go的異常退出場景1.因為數組/切片索引越界2.空指針調用3.過早關閉http響應體4.除以零5.向已經關閉的通道發送資訊6.重複關閉通道7.關閉未初始化的通道8.未初始化 map9.跨協程的“恐慌”處理10.sync計數為負值

2.空指針調用

package main

import "fmt"

type User struct {
	name string
}

func (u *User) GetName() string {
	return  u.name
}
func main() {
	s := &User{}
	s = nil
	name := s.GetName()
	fmt.Println(name)


}
           
Go的異常退出場景1.因為數組/切片索引越界2.空指針調用3.過早關閉http響應體4.除以零5.向已經關閉的通道發送資訊6.重複關閉通道7.關閉未初始化的通道8.未初始化 map9.跨協程的“恐慌”處理10.sync計數為負值

3.過早關閉http響應體

package main

import (
	"log"
	"net/http"
)

func main() {
	resp,err := http.Get("baidu.com")
	//1
	defer resp.Body.Close()
	if err != nil {
		log.Fatalf("http get err is : %s \n",err)
	}
	//2
	defer resp.Body.Close()

}
           

當defer在1的時候

Go的異常退出場景1.因為數組/切片索引越界2.空指針調用3.過早關閉http響應體4.除以零5.向已經關閉的通道發送資訊6.重複關閉通道7.關閉未初始化的通道8.未初始化 map9.跨協程的“恐慌”處理10.sync計數為負值

當defer在2的時候

Go的異常退出場景1.因為數組/切片索引越界2.空指針調用3.過早關閉http響應體4.除以零5.向已經關閉的通道發送資訊6.重複關閉通道7.關閉未初始化的通道8.未初始化 map9.跨協程的“恐慌”處理10.sync計數為負值

是以我們在做defer的時候一定要先做錯誤判斷 在做完了錯誤判斷之後我們才可以做defer 包括mysql的 db.close

4.除以零

package main

func D(a,b int) int{
	return a/b
}

func main() {
	D(1,0)
}
           
Go的異常退出場景1.因為數組/切片索引越界2.空指針調用3.過早關閉http響應體4.除以零5.向已經關閉的通道發送資訊6.重複關閉通道7.關閉未初始化的通道8.未初始化 map9.跨協程的“恐慌”處理10.sync計數為負值

5.向已經關閉的通道發送資訊

package main

func main() {
	ch := make(chan int,1)
	ch <- 1
	close(ch)
	ch <- 2
}
           
Go的異常退出場景1.因為數組/切片索引越界2.空指針調用3.過早關閉http響應體4.除以零5.向已經關閉的通道發送資訊6.重複關閉通道7.關閉未初始化的通道8.未初始化 map9.跨協程的“恐慌”處理10.sync計數為負值

6.重複關閉通道

package main

func main() {
	ch := make(chan int,1)
	ch <- 1
	close(ch)
	close(ch)
}
           
Go的異常退出場景1.因為數組/切片索引越界2.空指針調用3.過早關閉http響應體4.除以零5.向已經關閉的通道發送資訊6.重複關閉通道7.關閉未初始化的通道8.未初始化 map9.跨協程的“恐慌”處理10.sync計數為負值

7.關閉未初始化的通道

package main

func main() {
	var ch chan  int
	close(ch)
}
           
Go的異常退出場景1.因為數組/切片索引越界2.空指針調用3.過早關閉http響應體4.除以零5.向已經關閉的通道發送資訊6.重複關閉通道7.關閉未初始化的通道8.未初始化 map9.跨協程的“恐慌”處理10.sync計數為負值

8.未初始化 map

package main

func main() {
	var user map[string]int
	user["test"] = 1
}
           
Go的異常退出場景1.因為數組/切片索引越界2.空指針調用3.過早關閉http響應體4.除以零5.向已經關閉的通道發送資訊6.重複關閉通道7.關閉未初始化的通道8.未初始化 map9.跨協程的“恐慌”處理10.sync計數為負值

9.跨協程的“恐慌”處理

package main

import (
	"log"
	"time"
)

func main() {
	go func() {
		defer func() {
			if err := recover();err != nil {
				log.Fatalf("recover is err %v \n",err)
			}
		}()
		handler()
	}()
	time.Sleep(time.Second)
}

func handler() {
	go divide(1,0)
}
func divide(a,b int) int {
	return  a/b
}
           
Go的異常退出場景1.因為數組/切片索引越界2.空指針調用3.過早關閉http響應體4.除以零5.向已經關閉的通道發送資訊6.重複關閉通道7.關閉未初始化的通道8.未初始化 map9.跨協程的“恐慌”處理10.sync計數為負值

10.sync計數為負值

package main

import "sync"

func main() {
	wg := sync.WaitGroup{}
	wg.Done()
	wg.Wait()
}
           
Go的異常退出場景1.因為數組/切片索引越界2.空指針調用3.過早關閉http響應體4.除以零5.向已經關閉的通道發送資訊6.重複關閉通道7.關閉未初始化的通道8.未初始化 map9.跨協程的“恐慌”處理10.sync計數為負值