1、创建错误的方式
package main
import (
"errors"
"fmt"
)
func main() {
//1创建错误方式(1)
err1 := errors.New("do by try")
fmt.Println(err1)
fmt.Printf("%T\n",err1)
//2创建错误方式(2)
err2 := fmt.Errorf("错误信息码%d",404)
fmt.Println(err2)
fmt.Printf("%T\n",err2)
err3 := checkAge(1)
fmt.Println(err3)
}
func checkAge(age int)error{
if age<0{
err := fmt.Errorf("age must be positive")
return err
}
fmt.Printf("age = %d",age)
return nil
}
2、自定义错误
package main
import (
"fmt"
"math"
)
type areaError struct{
msg string
radius float64
}
func (e*areaError) Error()string{
return fmt.Sprintf("errror: radius,%.2f ,%s",e.radius,e.msg)
}
func circleArea(radius float64) (float64, error) {
if radius<0{
return 0,&areaError{"radius is illegal",radius}
}
return math.Pi*radius*radius,nil
}
func main() {
radius := -3.0
area ,err := circleArea(radius)
if err != nil {
fmt.Println(err)
if err,ok := err.(*areaError);ok{
fmt.Printf("radius=%.2f\n\n", err.radius)
}
return
}
fmt.Println("space=",area)
}
package main
import (
"fmt"
"math"
)
type areaError struct{
msg string
radius float64
height float64
}
func (e*areaError) Error()string{
return e.msg
}
func (e*areaError) heightError()bool{
return e. height<0
}
func (e*areaError) radiusError()bool{
return e.radius<0
}
func volumn(radius float64, height float64) (float64, error) {
msg := ""
if height<0 {
msg +="height<0 "
}
if radius<0 {
msg +="radius<0"
}
if msg != ""{
return 0,&areaError{msg,radius, height}
}
return math.Pi*radius*radius* height,nil
}
func main() {
radius := -3.0
height := 1.0
area , err := volumn(radius,height)
if err != nil{
fmt.Println(err)
if err,ok := err.(*areaError);ok{
fmt.Printf("error:半径:%.2f 高度:%.2f",err.radius,err. height)
}
}else{
fmt.Println("圆柱体体积:",area)
}
}
3、异常 panic和recover
package main
import "fmt"
func main(){
defer func(){
if msg := recover();msg != nil{
fmt.Println("在恐慌之前得以调用,程序此时解除恐慌")
}
}()
funA()
}
func funA(){
defer fmt.Println("发生恐慌这里第二个执行")
defer fmt.Println("发生恐慌这里第一个执行")
for i :=1;i<10;i++{
fmt.Println(i)
if(i==5){
//中断
panic("fun 函数自定义恐慌")
}
}
defer fmt.Println("发生恐慌,这里是不会执行")
}
4、defer简单案例
package main
import "fmt"
// go语言小知识 -- defer 延迟处理函数
/*
总结:
1、return之前有defer
2、return之前无defer
栈:值类型 int 内存连续
堆:引用类型 []int 不连续
逃逸分析
GC机制
*/
func main(){
a := test1()
fmt.Println(a)
}
func test()(i int){
defer func(){
i++
fmt.Println("1",i) //顺序(2) 1 2
}()
i = i+1
fmt.Println("2",i) // 顺序(1) 2 1
return i //顺序(3) 2
}
func test1()(n int){
var i int
defer func(){
i++
fmt.Println("1",i) //顺序(2) 1 2
}()
i = i+1
fmt.Println("2",i) // 顺序(1) 2 1
return i //顺序(3) 把i=1的值copy到栈,最后返回的是1
}
func test2()(i int){
if i==1{
fmt.Println("0",i)
return i
}
defer func(){
i++
fmt.Println("1",i) //顺序(2) 1 2
}()
i = i+1
fmt.Println("2",i) // 顺序(1) 2 1
return i //顺序(3) 2
}
func test3()(i int){
defer fmt.Println("1") // 顺序 (3)
defer fmt.Println("2") // 顺序 (2)
defer fmt.Println("3") // 顺序 (1)
return i // 顺序 (4)
}