1. 数组越界
- 场景说明:当访问数组、切片或字符串的索引超出其有效范围时,会发生
panic
。例如,试图访问一个长度为 5 的切片的第 6 个元素。
- 预防方法:在访问之前,确保索引在有效范围内。可以使用
len
函数获取切片或数组的长度,并进行边界检查。
- 代码示例:
package main
import "fmt"
func main() {
s := []int{1, 2, 3, 4, 5}
index := 10
if index < len(s) {
fmt.Println(s[index])
} else {
fmt.Println("Index out of range")
}
}
2. 空指针引用
- 场景说明:当试图对一个值为
nil
的指针进行解引用操作时,会触发 panic
。比如对一个 nil
的结构体指针调用方法。
- 预防方法:在使用指针之前,先检查指针是否为
nil
。
- 代码示例:
package main
import "fmt"
type Person struct {
Name string
}
func (p *Person) SayHello() {
if p != nil {
fmt.Printf("Hello, I'm %s\n", p.Name)
} else {
fmt.Println("Person is nil")
}
}
func main() {
var p *Person
p.SayHello()
}
3. 类型断言失败
- 场景说明:在进行类型断言时,如果实际类型与断言的类型不匹配,就会发生
panic
。例如,将一个 interface{}
类型的值断言为 int
,但实际是 string
。
- 预防方法:使用带检测的类型断言形式,即
value, ok := someInterface.(targetType)
,通过 ok
判断断言是否成功。
- 代码示例:
package main
import "fmt"
func main() {
var i interface{} = "hello"
if v, ok := i.(int); ok {
fmt.Println("The value is", v)
} else {
fmt.Println("Type assertion failed")
}
}
4. 除数为零
- 场景说明:在进行除法运算时,如果除数为零,会导致
panic
。
- 预防方法:在进行除法运算前,先检查除数是否为零。
- 代码示例:
package main
import "fmt"
func main() {
dividend := 10
divisor := 0
if divisor != 0 {
result := dividend / divisor
fmt.Println("Result:", result)
} else {
fmt.Println("Division by zero is not allowed")
}
}