error

error

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
package main

import (
	"errors"
	"fmt"
)

// const E0 = errors.New("can't open file") // 编译报错:errors.New("can't open file") (value of type error) is not constant
var e1 = errors.New("can't open file")

type denominatorErr struct {
	denominator int
	err         string
}

func (e *denominatorErr) Error() string {
	return fmt.Sprintf("%d - %s", e.denominator, e.err)
}

func Divide1(a, b int) (quotient, remainder int, err error) {
	if b == 0 {
		return 0, 0, &denominatorErr{0, "The divisor can't be 0."}
	}

	return a / b, a % b, nil
}

func Divide2(a, b int) (quotient, remainder int, err error) {
	if b == 0 {
		return 0, 0, fmt.Errorf("happen: %w", &denominatorErr{0, "The divisor can't be 0."})
	}

	return a / b, a % b, nil
}

func main() {
	fmt.Printf("%v|%T|%q\n", e1, e1, e1) // can't open file|*errors.errorString|"can't open file"happen: can't open file

	e2 := fmt.Errorf("happen: %w", e1)
	fmt.Printf("%v|%T|%q\n", e2, e2, e2) // happen: can't open file|*fmt.wrapError|"happen: can't open file"

	fmt.Println(errors.Is(e2, e1)) //true
	if errors.Is(e2, e1) {
		fmt.Println("在e2中匹配到e1的错误") // 在e2中匹配到e1的错误
	}

	_, _, err := Divide1(2, 0)
	fmt.Printf("%v|%T|%q\n", err, err, err) // 0 - The divisor can't be 0.|*main.denominatorErr|"0 - The divisor can't be 0."
	if deErr, ok := err.(*denominatorErr); ok {
		fmt.Println(deErr.denominator) // 0
		fmt.Println(deErr.err)         // The divisor can't be 0.
	}

	_, _, err = Divide2(2, 0)
	fmt.Printf("%v|%T|%q\n", err, err, err) // happen: 0 - The divisor can't be 0.|*fmt.wrapError|"happen: 0 - The divisor can't be 0."
	//var targetErr denominatorErr // panic: errors: *target must be interface or implement error
	var targetErr *denominatorErr
	if errors.As(err, &targetErr) {
		fmt.Println(targetErr.denominator) // 0
		fmt.Println(targetErr.err)         // The divisor can't be 0.
	}

	fmt.Println(Divide1(3, 2)) // 1 1 <nil>
	fmt.Println(Divide2(3, 2)) // 1 1 <nil>

}
最后修改 March 10, 2024: 更新 (ddf4687)