文章目录
- 1.内存管理
- 1.切片长度校验
- 2.指针判空
- 3.整数安全
1.内存管理
1.切片长度校验
在对 slice 进行操作时,必须判断长度是否合法,防止程序 panic。
代码语言:javascript复制// bad: slice bounds out of range
func foo(slice []int){
fmt.Println(slice[:10])
}
// good: check the slice length
func foo(slice []int){
if len(slice) >= 10 {
fmt.Println(slice[:10])
return
}
fmt.Println("no enough elems in slice")
}
2.指针判空
进行指针操作时,必须判断该指针是否为 nil,防止程序 panic,尤其在进行结构体Unmarshal 时。
代码语言:javascript复制type Packet struct {
Type uint8
Version uint8
Data *Data
}
type Data struct {
Stat uint8
Len uint8
Buf [8]byte
}
// bad
func foo(p Packet) {
fmt.Println(p.Data.Stat)
}
// good
func foo(p Packet) {
if p.Data != nil {
fmt.Println(p.Data.Stat)
return
}
fmt.Println("packet is nil")
}
3.整数安全
在进行数字运算操作时,需要做好长度限制,防止外部输入运算导致异常:
- 确保无符号整数运算时不会出现符号反转
- 确保有符号整数运算时不会出现溢出
// bad:未限制长度,导致整数溢出
func overflow(n int32) {
var num int32 = 0
num = n 1
// 对长度限制不当,导致整数溢出
fmt.Printf("%dn", num)
// 使用 numInt,可能导致其他错误
}
func main() {
overflow(2147483647)
}
// good
func overflow(n int32) {
var num int32 = 0
num = n 1
if num < 0 {
fmt.Println("integer overflow")
return
}
fmt.Println("integer ok")
}
func main(){
overflow(2147483647)
}
- 确保整型转换时不会出现截断错误
- 确保整型转换时不会出现符号错误
以下场景必须严格进行长度限制:
- 作为数组索引
- 作为对象的长度或者大小
- 作为数组的边界(如作为循环计数器)