当前位置:网站首页>学习 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
边栏推荐
- Mysql8. 0 installation guide
- Microsoft Access database using PHP PDO ODBC sample
- Mba-day5 Mathematics - application problems - engineering problems
- 全栈交叉编译X86完成过程经验分享
- MySQL Router重装后重新连接集群进行引导出现的——此主机中之前已配置过的问题
- JVM - common parameters
- Intuitive understanding entropy
- Read integrity monitoring techniques for vision navigation systems
- 比深度学习更值得信赖的模型ART
- Source insight 4.0 FAQs
猜你喜欢

MySQL Router重装后重新连接集群进行引导出现的——此主机中之前已配置过的问题

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

More reliable model art than deep learning

Visualized common drawing (II) line chart

ConstraintLayout布局

数据库管理软件SQLPro for SQLite for Mac 2022.30

【leetcode】107. Sequence traversal of binary tree II

After the MySQL router is reinstalled, it reconnects to the cluster for boot - a problem that has been configured in this host before

SVN的使用:

Mysql8.0安装指南
随机推荐
Problems of class in C # and database connection
Common parameters of ffmpeg command line
How to Ping Baidu development board
App. In wechat applet JS files, components, APIs
Introduction to data analysis 𞓜 kaggle Titanic mission (IV) - > data cleaning and feature processing
Reading integrity monitoring techniques for vision navigation systems - 5 Results
Swagger2 接口如何导入Postman
Learning notes 7-depth neural network optimization
Ueditor -- limitation of 4m size of image upload component
Alarm scene recognition
Deploy jar package
MySql常用语句
Visual common drawing (V) scatter diagram
Kaggle - real battle of house price prediction
使用zerotier让异地设备组局域网
GO接口使用
Code implementation of general bubbling, selection, insertion, hill and quick sorting
SQL server query database deadlock
Mysql8.0安装指南
Jupyter Lab 十大高生产力插件