go程序异常painc 退出的场景
引用书籍《Go语言编程之旅》
1.因为数组/切片索引越界
package main
import "fmt"
func main() {
names := []string{
"test",
"test2",
}
name := names[len(names)]
fmt.Println(name)
}
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)
}
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的时候
当defer在2的时候
所以我们在做defer的时候一定要先做错误判断 在做完了错误判断之后我们才可以做defer 包括mysql的 db.close
4.除以零
package main
func D(a,b int) int{
return a/b
}
func main() {
D(1,0)
}
5.向已经关闭的通道发送信息
package main
func main() {
ch := make(chan int,1)
ch <- 1
close(ch)
ch <- 2
}
6.重复关闭通道
package main
func main() {
ch := make(chan int,1)
ch <- 1
close(ch)
close(ch)
}
7.关闭未初始化的通道
package main
func main() {
var ch chan int
close(ch)
}
8.未初始化 map
package main
func main() {
var user map[string]int
user["test"] = 1
}
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
}
10.sync计数为负值
package main
import "sync"
func main() {
wg := sync.WaitGroup{}
wg.Done()
wg.Wait()
}