Go里面的接口属于比较难理解的概念,通过它独特的错误处理方式可以帮助学习接口。
Go的错误类型使用error类型,它其实就是一个实现了Error()函数的接口:
type error interface {
Error() string
}
所以再自定义一个错误类型,只需要实现其中的Error()函数即可。以官网给的练习为例:
package main
import (
"fmt"
)
type ErrNegativeSqrt float64
func (e ErrNegativeSqrt) Error() string{
var ans string
ans=fmt.Sprintf("cannot Sqrt negative number: %v",float64(e))
return ans
}
func Sqrt(x float64) (float64, error) {
if x<0.0{
return 0, ErrNegativeSqrt(x)
}
z:=float64(1)
delta:=0.00001
var temp float64
for i:=0;i<10;i++{
temp=z
z=z-(z*z-x)/2.0/z;
if(z-temp<delta){
break;
}
}
return z,nil
}
func main() {
fmt.Println(Sqrt(2))
fmt.Println(Sqrt(-2))
}
在上面的代码中,从float64实现了一个自定义类型ErrNegativeSqrt。我们需要error类型能返回一个字符串就行,但是这里想让它与数据有关,所以从float64来type。只要给它增加Error()方法,就可以在需要返回error类型的地方返回一个ErrNegativeSqrt,fmt会自动将Error()返回的字符串当做错误信息打印出来。(当然也可以通过Error()函数手动获得这个字符串)。接下来用从struct来type的自定义错误类型来重写上面那个程序:
package main
import (
"fmt"
)
//自定义一个错误类型
//type ErrNegativeSqrt float64
//自定义一个错误类型
type Err struct {
value float64
info string
}
//实现error接口
func (e Err) Error() string {
e.info = fmt.Sprintf("cannot Sqrt negative number: %v", e.value)
return e.info
}
/*//实现error接口
func (e ErrNegativeSqrt) Error() string {
var ans string
ans = fmt.Sprintf("cannot Sqrt negative number: %v", float64(e))
return ans
}*/
//牛顿法求平方根
func Sqrt(x float64) (float64, error) {
if x < 0.0 {
var e Err
e.value = x
e.info = e.Error()
return 0, e
}
z := float64(1)
delta := 0.00001
var temp float64
for i := 0; i < 10; i++ {
temp = z
z = z - (z*z-x)/2.0/z
if z-temp < delta {
break
}
}
return z, nil
}
func main() {
fmt.Println(Sqrt(2))
fmt.Println(Sqrt(-2))
}
这回把错误信息单独保存成一个字符串,可以随时调用该字段,上面两个程序的执行结果完全一样。