如何让错误处理更加优雅

1.go 采用c 的err方法,但是容易产生大量的外部判断。

package killer

import "fmt"

type Book struct {
    Name   string
    Price  int
    Store  int
    Member int
}

func clientExample() {
    book := &Book{
        Name:   "golang",
        Price:  100,
        Store:  100,
        Member: 1,
    }
    err := book.CalcDiscount(99)
    if err != nil {
        return
    }
    err = book.JuedeIfStore()
    if err != nil {
        return
    }
    err = book.IfSale()
    if err != nil {
        return
    }
    err = book.CalcTotal()
    if err != nil {
        return
    }
    fmt.Println("ok")
}
func (b *Book) CalcDiscount(count int) error {
    // ...
    b.Price = b.Price * count / 100
    err := SomeError()
    if err != nil {
        return err
    }
    return nil
}
func (b *Book) JuedeIfStore() error {

    return nil
}
func (b *Book) IfSale() error {
    // ...
    return nil
}
func (b *Book) CalcTotal() error {
    // ...
    return nil
}
func (b *Book) AddPay() error {
    // ...
    return nil
}
func (b *Book) AddOrder() error {
    // ...
    return nil
}

func SomeError() error {
    return fmt.Errorf("some error")
}
View Code

2.如果一个结构体中有大量的错误需要判断,那么可以这样

 1 package killer
 2 
 3 import "fmt"
 4 
 5 func someError() error {
 6     return fmt.Errorf("some error")
 7 }
 8 
 9 type Book2 struct {
10     Name   string
11     Price  int
12     Store  int
13     Member int
14     error  error
15 }
16 
17 func clientExample2() {
18     book2 := &Book2{
19         Name:   "golang",
20         Price:  100,
21         Store:  100,
22         Member: 1,
23     }
24     book2.CalcDiscount(99).
25         JuedeIfStore().
26         IfSale().
27         AddPay().
28         AddOrder().
29         CheckAll()
30 
31     fmt.Println("ok")
32 
33 }
34 
35 func (b *Book2) CalcDiscount(count int) *Book2 {
36     if b.error != nil {
37         return b
38     }
39     // 具体的业务逻辑..
40     b.error = someError()
41     return b
42 }
43 
44 func (b *Book2) JuedeIfStore() *Book2 {
45     if b.error != nil {
46         return b
47     }
48     // 具体的业务逻辑
49     return b
50 }
51 func (b *Book2) IfSale() *Book2 {
52     if b.error != nil {
53         return b
54     }
55     return b
56 }
57 func (b *Book2) CalcTotal() *Book2 {
58     if b.error != nil {
59         return b
60     }
61     return b
62 }
63 func (b *Book2) AddPay() *Book2 {
64     if b.error != nil {
65         return b
66     }
67     return b
68 }
69 func (b *Book2) AddOrder() *Book2 {
70     if b.error != nil {
71         return b
72     }
73     return b
74 }
75 
76 func (b *Book2) CheckAll() *Book2 {
77     if b.error != nil {
78         return b
79     }
80     return b
81 }
View Code

2.1 把错误集中到结构体的属性中

2.2 让error在不同的方法中以值的形式传递下去

2.3 在每个方法的前面先判断一下这个error是否存在,如果存在则退出

2.4 否则进入正常的业务处理,当发生错误的时候,给他赋值,让下一个方法处理

2.5 调用的时候可以形成漂亮的链式调用

 

posted @ 2023-03-03 16:17  易先讯  阅读(9)  评论(0编辑  收藏  举报