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 错误处理
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) }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
//以下捕获失败 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") }使用场景
一般情况下有两种情况用到:
2173Go 语言接口
将接口做为参数
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) }输出结果:
2172Go 语言接口
接口案例:
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() }2171Go 语言接口
接口方法传参,以及返回结果:
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) }