练习题
从先前的练习中复制 Sqrt
函数,并修改使其多返回一个 error
值。
由于不支持复数,当 Sqrt
接收到一个负数时,应当返回一个非 nil
的错误值。
创建一个新类型
type ErrNegativeSqrt float64
为其实现
func (e ErrNegativeSqrt) Error() string
使其成为一个 error
, 该方法就可以让 ErrNegativeSqrt(-2).Error()
返回 "cannot Sqrt negative number: -2"
。
注意:在
Error
方法内调用fmt.Sprint(e)
将会让程序陷入死循环。可以通过先转换e
来避免这个问题:fmt.Sprint(float64(e))
。请思考这是为什么呢?
修改 Sqrt
函数,使其接受一个负数时,返回 ErrNegativeSqrt
值。
提示代码
// exercise-errors.go
package main
import (
"fmt"
)
func Sqrt(x float64) (float64, error) {
return 0, nil
}
func main() {
fmt.Println(Sqrt(2))
fmt.Println(Sqrt(-2))
}
我的解答
// exercise-errors.go
package main
import (
"fmt"
)
type ErrSqrt float64
func (e ErrSqrt) Error() string {
return fmt.Sprint("cannot Sqrt negative number: ", float64(e))
}
func Sqrt(x float64) (float64, error) {
if x <= 0{
err := ErrSqrt(x)
return 0, err
}
z,d := 1.0, 1000.0
// 无限循环
for {
old := z
z = z - (z*z-x)/(2*z)
// z = z + (x/z-z)/2
// 当本次计算结果和上次结果 在小数点后d位相同时停止
if uint(z*d) == uint(old*d) {
return z,nil
}
// fmt.Println(z)
}
return 0, nil
}
func main() {
fmt.Println(Sqrt(2))
fmt.Println(Sqrt(-2))
}
OUT:
1.4142135623746899 <nil>
0 cannot Sqrt negative number: -2