自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Golang 語言怎么避免引發(fā) Panic?

開發(fā) 后端
本文我們介紹 Golang 語言中容易引發(fā) panic 的場(chǎng)景,尤其是空指針操作是最容易踩坑的場(chǎng)景,我們?cè)诔绦蜷_發(fā)中,一定要小心使用指針類型。

[[439971]]

01介紹

在 Golang 語言中,程序引發(fā) panic 會(huì)導(dǎo)致程序崩潰,所以我們?cè)诔绦蜷_發(fā)時(shí),需要特別小心,避免引發(fā) panic。本文我們介紹 Golang 語言中比較容易引發(fā) panic 的操作。

02指針

任意一種編程語言都會(huì)使用函數(shù),我們使用 Golang 編寫函數(shù)或方法時(shí),經(jīng)常會(huì)用到指針類型的返回值,這時(shí)如果執(zhí)行調(diào)用空指針(指針未初始化或值為 nil),對(duì)于新手而言,就很容易引發(fā)程序 panic。

  1. type User struct { 
  2.  Name string 
  3.  Age  int 
  4.  
  5. func (u *User) GetInfo() (data *User) { 
  6.  data = &User
  7.   Name"frank"
  8.   Age:  18, 
  9.  } 
  10.  return data 
  11.  
  12. func main() { 
  13.  user := new(User
  14.  userInfo := user.GetInfo() 
  15.  fmt.Println(userInfo) 
  16.  if userInfo.Age >= 18 { 
  17.   fmt.Println("this is a man"
  18.  } 

我們閱讀上面這段代碼,這是一段非常簡單的返回值為指針類型的示例代碼,讀者朋友們?cè)囅胍幌隆?/p>

如果 GetInfo 方法體中的 data 的值來源于調(diào)用另外一個(gè)函數(shù)或方法,被調(diào)用的這個(gè)函數(shù)或方法返回值是 nil,而我們 main 函數(shù)中會(huì)使用返回值的 Age 字段作為判定條件,這時(shí)程序就會(huì)引發(fā) panic,導(dǎo)致程序崩潰。

所以,我們?cè)谑褂弥羔橆愋蜁r(shí),要特別小心,不然我們就只能在調(diào)用函數(shù)或方法之前,使用 defer 和 recover 添加一段補(bǔ)償代碼,我個(gè)人感覺不是很優(yōu)雅。

  1. defer func() { 
  2.   if err := recover(); err != nil { 
  3.    fmt.Println("err = ", err) 
  4.   } 
  5.  }() 

我一般是在判定指針類型的返回值時(shí),為了避免程序引發(fā) panic,我會(huì)加一個(gè)且(&&)的判定條件,判定返回值不是 nil,并且返回值的某個(gè)字段符合某種條件。

  1. func main() { 
  2.  ... 
  3.    
  4.  if userInfo != nil && userInfo.Age >= 18 { 
  5.   fmt.Println("this is a man"
  6.  } 

03數(shù)組和切片

數(shù)組和切片類型,當(dāng)我們?cè)浇缭L問時(shí),也會(huì)引發(fā) panic,導(dǎo)致程序崩潰。不過,一般 IDE 可以提示數(shù)組越界訪問的錯(cuò)誤,如果讀者朋友使用的編輯器不會(huì)提示數(shù)組越界的錯(cuò)誤,那你使用數(shù)組也要小心了。

  1. func main() { 
  2.  code := []string{"php""golang"
  3.  fmt.Printf("len:%d cap:%d val:%s \n", len(code), cap(code), code) 
  4.  fmt.Println(code[2]) 

04通道

如果我們關(guān)閉未初始化的通道,重復(fù)關(guān)閉通道,向已經(jīng)關(guān)閉的通道中發(fā)送數(shù)據(jù),這三種情況也會(huì)引發(fā) panic,導(dǎo)致程序崩潰。

  1. func main() { 
  2.  var ch chan int 
  3.  // close(ch) 
  4.  ch = make(chan int, 1) 
  5.  ch <- 1 
  6.  // close(ch) 
  7.  // close(ch) 
  8.  ch <- 2 

05映射

如果我們直接操作未初始化的映射(map),也會(huì)引發(fā) panic,導(dǎo)致程序崩潰。

  1. func main() { 
  2.  var m map[string]int 
  3.  // m = make(map[string]int
  4.  m["php"] = 80 

另外,操作映射可能會(huì)遇到的更為嚴(yán)重的一個(gè)問題是,同時(shí)對(duì)同一個(gè)映射并發(fā)讀寫,它會(huì)觸發(fā) runtime.throw,不像 panic 可以使用 recover 捕獲。所以,我們?cè)趯?duì)同一個(gè)映射并發(fā)讀寫時(shí),一定要使用鎖。

  1. func main() { 
  2.  var m map[string]int 
  3.  m = make(map[string]int
  4.  go func(map[string]int) { 
  5.   for { 
  6.    m["php"] = 80 
  7.   } 
  8.  }(m) 
  9.  
  10.  go func(map[string]int) { 
  11.   for { 
  12.    _ = m["php"
  13.   } 
  14.  }(m) 
  15.  
  16.  time.Sleep(time.Second

輸出結(jié)果:

  1. fatal error: concurrent map read and map write 
  2.  
  3. goroutine 7 [running]: 
  4. runtime.throw({0x10a7510, 0x0}) 
  5.         /usr/local/opt/go/libexec/src/runtime/panic.go:1198 +0x71 fp=0xc000050f28 sp=0xc000050ef8 pc=0x102fa51 

06類型斷言

如果類型斷言使用不當(dāng),比如我們不接收布爾值的話,類型斷言失敗也會(huì)引發(fā) panic,導(dǎo)致程序崩潰。

  1. func main() { 
  2.  var name interface{} = "frank" 
  3.  // a, ok := name.(int
  4.  // fmt.Println(a, ok) 
  5.  a := name.(int
  6.  fmt.Println(a) 

07總結(jié)

 

本文我們介紹 Golang 語言中容易引發(fā) panic 的場(chǎng)景,尤其是空指針操作是最容易踩坑的場(chǎng)景,我們?cè)诔绦蜷_發(fā)中,一定要小心使用指針類型。

 

責(zé)任編輯:武曉燕 來源: Golang語言開發(fā)棧
相關(guān)推薦

2022-01-04 23:13:57

語言PanicGolang

2021-09-13 05:02:49

GogRPC語言

2021-06-09 23:36:46

Golang語言版本

2021-10-10 23:02:49

Golang語言代碼

2021-06-29 23:40:19

Golang語言并發(fā)

2021-11-08 23:09:07

Go排序數(shù)據(jù)

2021-06-07 23:19:44

Golang語言 Defer

2023-10-09 07:14:42

panicGo語言

2021-10-31 23:01:50

語言拼接字符串

2025-03-12 12:03:10

2013-03-22 09:34:13

2021-07-12 05:05:59

Golang語言字段

2021-01-29 08:56:13

Golang標(biāo)準(zhǔn)庫函數(shù)

2025-03-31 00:29:44

2018-10-14 15:52:46

MySQL數(shù)據(jù)清理數(shù)據(jù)庫

2023-05-06 09:36:38

RecoverPanic

2022-01-09 23:04:19

語言打印結(jié)構(gòu)體

2020-12-22 10:29:43

漏洞SAML認(rèn)證補(bǔ)丁

2018-08-01 15:10:02

GolangPython語言

2025-02-06 13:19:31

RustPin系統(tǒng)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)