if result, errorMsg := Divide(100, 10); errorMsg == "" { fmt.Println("100/10 = ", result) } if _, errorMsg := Divide(100, 0); errorMsg != "" { fmt.Println("errorMsg is: ", errorMsg) }
等价于:
result, errorMsg := Divide(100,10) if errorMsg == ""{ fmt.Println("100/10 = ", result) } result, errorMsg = Divide(100,0) if errorMsg != ""{ fmt.Println("errorMsg is: ", errorMsg) }
这里应该介绍一下 panic 与 recover,一个用于主动抛出错误,一个用于捕获panic抛出的错误。
概念
panic 与 recover 是 Go 的两个内置函数,这两个内置函数用于处理 Go 运行时的错误,panic 用于主动抛出错误,recover 用来捕获 panic 抛出的错误。
panic
defer
recover
recover()
nil
例子1
//以下捕获失败 defer recover() defer fmt.Prinntln(recover) defer func(){ func(){ recover() //无效,嵌套两层 }() }() //以下捕获有效 defer func(){ recover() }() func except(){ recover() } func test(){ defer except() panic("runtime error") }
例子2
多个panic只会捕捉最后一个:
package main import "fmt" func main(){ defer func(){ if err := recover() ; err != nil { fmt.Println(err) } }() defer func(){ panic("three") }() defer func(){ panic("two") }() panic("one") }
使用场景
一般情况下有两种情况用到:
将接口做为参数
package main import ( "fmt" ) type Phone interface { call() string } type Android struct { brand string } type IPhone struct { version string } func (android Android) call() string { return "I am Android " + android.brand } func (iPhone IPhone) call() string { return "I am iPhone " + iPhone.version } func printCall(p Phone) { fmt.Println(p.call() + ", I can call you!") } func main() { var vivo = Android{brand:"Vivo"} var hw = Android{"HuaWei"} i7 := IPhone{"7 Plus"} ix := IPhone{"X"} printCall(vivo) printCall(hw) printCall(i7) printCall(ix) }
输出结果:
I am Android Vivo, I can call you! I am Android HuaWei, I can call you! I am iPhone 7 Plus, I can call you! I am iPhone X, I can call you!
接口案例:
package main import ( "fmt" ) //定义接口 type Phone interface { call() call2() } //一直都搞不懂这是干啥的 //原来是用来定义结构体内的数据类型的 type Phone1 struct { id int name string category_id int category_name string } //第一个类的第一个回调函数 func (test Phone1) call() { fmt.Println("这是第一个类的第一个接口回调函数 结构体数据:", Phone1{id: 1, name: "浅笑"}) } //第一个类的第二个回调函数 func (test Phone1) call2() { fmt.Println("这是一个类的第二个接口回调函数call2", Phone1{id: 1, name: "浅笑", category_id: 4, category_name: "分类名称"}) } //第二个结构体的数据类型 type Phone2 struct { member_id int member_balance float32 member_sex bool member_nickname string } //第二个类的第一个回调函数 func (test2 Phone2) call() { fmt.Println("这是第二个类的第一个接口回调函数call", Phone2{member_id: 22, member_balance: 15.23, member_sex: false, member_nickname: "浅笑18"}) } //第二个类的第二个回调函数 func (test2 Phone2) call2() { fmt.Println("这是第二个类的第二个接口回调函数call2", Phone2{member_id: 44, member_balance: 100, member_sex: true, member_nickname: "陈超"}) } //开始运行 func main() { var phone Phone //先实例化第一个接口 phone = new(Phone1) phone.call() phone.call2() //实例化第二个接口 phone = new(Phone2) phone.call() phone.call2() }
接口方法传参,以及返回结果:
package main import "fmt" type Phone interface { call(param int) string takephoto() } type Huawei struct { } func (huawei Huawei) call(param int) string{ fmt.Println("i am Huawei, i can call you!", param) return "damon" } func (huawei Huawei) takephoto() { fmt.Println("i can take a photo for you") } func main(){ var phone Phone phone = new(Huawei) phone.takephoto() r := phone.call(50) fmt.Println(r) }
感谢您的支持,我会继续努力的!
支付宝扫一扫,即可进行扫码打赏哦
2175Go 错误处理
等价于:
2174Go 错误处理
这里应该介绍一下 panic 与 recover,一个用于主动抛出错误,一个用于捕获panic抛出的错误。
概念
panic 与 recover 是 Go 的两个内置函数,这两个内置函数用于处理 Go 运行时的错误,panic 用于主动抛出错误,recover 用来捕获 panic 抛出的错误。
panic
有两种情况,一是程序主动调用,二是程序产生运行时错误,由运行时检测并退出。panic
后,程序会从调用panic
的函数位置或发生panic
的地方立即返回,逐层向上执行函数的defer
语句,然后逐层打印函数调用堆栈,直到被recover
捕获或运行到最外层函数。panic
不但可以在函数正常流程中抛出,在defer
逻辑里也可以再次调用panic
或抛出panic
。defer
里面的panic
能够被后续执行的defer
捕获。recover
用来捕获panic
,阻止panic
继续向上传递。recover()
和defer
一起使用,但是defer
只有在后面的函数体内直接被掉用才能捕获panic
来终止异常,否则返回nil
,异常继续向外传递。例子1
例子2
多个panic只会捕捉最后一个:
使用场景
一般情况下有两种情况用到:
2173Go 语言接口
将接口做为参数
输出结果:
2172Go 语言接口
接口案例:
2171Go 语言接口
接口方法传参,以及返回结果: