当前位置:网站首页>学习 Go 语言 0x08:《Go 语言之旅》中 练习使用 error
学习 Go 语言 0x08:《Go 语言之旅》中 练习使用 error
2022-04-23 11:02:00 【爱博客大伯】
* 题目
https://tour.go-zh.org/methods/20
练习:错误
从之前的练习中复制 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 值。
* 代码
package main
import (
"fmt"
)
type ErrNegativeSqrt float64
func (e ErrNegativeSqrt) Error() string {
return fmt.Sprintf("cannot Sqrt negative number: %v", float64(e))
}
func Sqrt(x float64) (float64, error) {
if x < 0 {
return 0, ErrNegativeSqrt(x)
}
z := 1.0
for i := 1; i < 10; i++ {
z -= (z*z - x) / (2*z)
}
return z, nil
}
func main() {
fmt.Println(Sqrt(2))
fmt.Println(Sqrt(-2))
}
输出:
1.4142135623730951 <nil>
0 cannot Sqrt negative number: -2
* 将 fmt.Sprint(float64(e)) 改为 fmt.Sprint(e), 将会栈溢出
如果 把 fmt.Sprintf("cannot Sqrt negative number: %v", float64(e)) 改成 fmt.Sprintf("cannot Sqrt negative number: %v", e),运行结果为:
1.4142135623730951 <nil>
runtime: goroutine stack exceeds 250000000-byte limit
fatal error: stack overflow
runtime stack:
runtime.throw(0x1054d9, 0xe)
/usr/local/go/src/runtime/panic.go:617 +0x80
runtime.newstack()
/usr/local/go/src/runtime/stack.go:1041 +0x960
runtime.morestack()
/usr/local/go/src/runtime/asm_amd64p32.s:299 +0xc0
goroutine 1 [running]:
sync.(*Mutex).Lock(0x3422094, 0x0)
/usr/local/go/src/sync/mutex.go:72 +0x3a0 fp=0x8c00360 sp=0x8c00358 pc=0x99b80
sync.(*Pool).getSlow(0x1ad078, 0x8, 0x3422080, 0x0)
/usr/local/go/src/sync/pool.go:165 +0xe0 fp=0x8c00390 sp=0x8c00360 pc=0x9a400
sync.(*Pool).Get(0x1ad078, 0x1b4540, 0xfefc0004, 0x0)
/usr/local/go/src/sync/pool.go:141 +0x1a0 fp=0x8c003b8 sp=0x8c00390 pc=0x9a2a0
fmt.newPrinter(0x8c003f0, 0x0)
/usr/local/go/src/fmt/print.go:134 +0x40 fp=0x8c003d0 sp=0x8c003b8 pc=0xce6e0
fmt.Sprintf(0x1082ef, 0x1f, 0x8c00420, 0x1, 0x1, 0x8c00438, 0x18, 0x139f)
/usr/local/go/src/fmt/print.go:213 +0x20 fp=0x8c00400 sp=0x8c003d0 pc=0xcec40
main.ErrNegativeSqrt.Error(...)
/tmp/sandbox804641635/main.go:10
main.(*ErrNegativeSqrt).Error(0x67a3330, 0x122ecc, 0x67c7300, 0xf1b40)
<autogenerated>:1 +0xc0 fp=0x8c00430 sp=0x8c00400 pc=0xd97c0
fmt.(*pp).handleMethods(0x67c7300, 0x76, 0x6cd01, 0x139f)
/usr/local/go/src/fmt/print.go:610 +0x1e0 fp=0x8c00480 sp=0x8c00430 pc=0xd2480
fmt.(*pp).printArg(0x67c7300, 0xf1b40, 0x67a3330, 0x76)
/usr/local/go/src/fmt/print.go:699 +0x260 fp=0x8c004d0 sp=0x8c00480 pc=0xd2d00
fmt.(*pp).doPrintf(0x67c7300, 0x1082ef, 0x1f, 0x8c00598, 0x1, 0x1)
/usr/local/go/src/fmt/print.go:1016 +0x180 fp=0x8c00548 sp=0x8c004d0 pc=0xd7640
fmt.Sprintf(0x1082ef, 0x1f, 0x8c00598, 0x1, 0x1, 0x8c005b0, 0x18, 0x139f)
/usr/local/go/src/fmt/print.go:214 +0x60 fp=0x8c00578 sp=0x8c00548 pc=0xcec80
main.ErrNegativeSqrt.Error(...)
/tmp/sandbox804641635/main.go:10
略 (还有很多log)
对代码死循环的理解:
有问题的代码,如下:
func (e ErrNegativeSqrt) Error() string {
return fmt.Sprintf("cannot Sqrt negative number: %v", e)
}
第一次执行 ErrNegativeSqrt 的 Error()函数,是由 main函数中的 fmt.Println(Sqrt(-2)) 触发的。Sqrt(-2) 返回 error 为 ErrNegativeSqrt,在main中打印这个 error,就会执行 ErrNegativeSqrt 的 Error()函数。
然后在 Error()函数内部,执行 fmt.Sprintf("cannot Sqrt negative number: %v", e),e为ErrNegativeSqrt ,所以,再一次打印 ErrNegativeSqrt,所以,还会调用 ErrNegativeSqrt 的 Error()函数。这样就出现了死循环,直到调用栈溢出报错。
版权声明
本文为[爱博客大伯]所创,转载请带上原文链接,感谢
https://blog.csdn.net/u013553529/article/details/88919789
边栏推荐
- ConstraintLayout布局
- Kaggle - real battle of house price prediction
- Go interface usage
- 关于JUC三大常用辅助类
- 【leetcode】107. Sequence traversal of binary tree II
- 一个微博数据库设计带来的简单思考
- How to bind a process to a specified CPU
- ID number verification system based on visual structure - Raspberry implementation
- 【leetcode】102. Sequence traversal of binary tree
- 学习网站资料
猜你喜欢

Excel·VBA数组冒泡排序函数

使用 PHP PDO ODBC 示例的 Microsoft Access 数据库

JVM - common parameters

比深度学习更值得信赖的模型ART

How to quickly download vscode

使用zerotier让异地设备组局域网

Solution architect's small bag - 5 types of architecture diagrams

Introduction to data analysis 𞓜 kaggle Titanic mission (IV) - > data cleaning and feature processing

Download and installation steps of xshell + xftp

【leetcode】199.二叉树的右视图
随机推荐
Solutions to common problems in visualization (IX) background color
Mba-day6 logic - hypothetical reasoning exercises
Diary of dishes | Blue Bridge Cup - hexadecimal to octal (hand torn version) with hexadecimal conversion notes
About the three commonly used auxiliary classes of JUC
The difference between restful and soap
Cumcm 2021 - B: préparation d'oléfines C4 par couplage éthanol (2)
Excel·VBA自定义函数获取单元格多数值
VScode
精彩回顾|「源」来如此 第六期 - 开源经济与产业投资
Problems of class in C # and database connection
Source insight 4.0 FAQs
Google Earth engine (GEE) - scale up the original image (taking Hainan as an example)
Esp32 learning - add folder to project
Understand the key points of complement
一个微博数据库设计带来的简单思考
MySQL Router重装后重新连接集群进行引导出现的——此主机中之前已配置过的问题
Software testers, how to mention bugs?
Visual common drawing (V) scatter diagram
期货开户哪个公司好?安全靠谱的期货公司谁能推荐几家?
妊娠箱和分娩箱的区别