上一章结束了接口 interface
的探索,这一章继续探索 go 语言。
我们来看下 go 语言中是怎么处理报错 Errors 的。
在 go 语言中,定义了 error 接口:
type error interface {
Error() string
}
当 fmt 包要尝试打印一个 error 类型的数据时,它会调用 Error 方法来获取要打印的内容。
在 go 语言中,经常会看到如下的代码:
i, err := strconv.Atoi("42") // 在调用函数的同时,用 err 变量来接收报错
if err != nil { // 直接判断并处理函数报错
fmt.Printf("couldn't convert number: %v\n", err)
return
}
fmt.Println("Converted integer:", i)
go 语言推荐在每次函数调用后,及时处理报错。算是强制开发人员处理好边际问题(side case),这是一个好的开发范式,但是也让代码逻辑看起来不够连贯。
来看下官方给的示例代码:
package main
import (
"fmt"
"time"
)
type MyError struct { // 自定义报错 MyError
When time.Time
What string
}
func (e *MyError) Error() string { // 实现 Error 方法,即实现 error 接口
return fmt.Sprintf("at %v, %s",
e.When, e.What)
}
func run() error { // 一个返回报错的函数
return &MyError{
time.Now(),
"it didn't work",
}
}
func main() {
if err := run(); err != nil {
fmt.Println(err) // 打印报错内容
}
}
我们来实战一个返回“值和报错”的函数:
package main
import (
"fmt"
)
type ErrNegativeSqrt float64 // 声明自定义类型报错
func (e ErrNegativeSqrt) Error() string { // 实现 error 接口的 Error 方法
return fmt.Sprintf("cannot Sqrt negative number: %f", e)
}
func Sqrt(x float64) (float64, error) { // 定义函数实现开方计算,返回值是 float64 和 error
if x < 0 { // 当开方数小于0的时候,返回报错
return x, ErrNegativeSqrt(-2)
}
z := 1.0
for i := 0; i < 10; i++ {
z -= (z*z - x) / (2*z)
// fmt.Println(z)
}
return z, nil
}
func main() {
fmt.Println(Sqrt(2))
fmt.Println(Sqrt(-2))
}
在实际工作中,经常打交道的都是上面这一类的函数,需要我们谨慎小心的处理好返回的错误,让代码更加的健壮,让程序运行的更加稳定。
ok,这一章先这样~