-
Notifications
You must be signed in to change notification settings - Fork 26
/
errors.go
66 lines (57 loc) · 1.72 KB
/
errors.go
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"
)
// By convention, errors are the last return value and have type error, a built-in interface.
func f1(arg int) (int, error) {
if arg == 42 {
// errors.New constructs a basic error value with the given error message.
return -1, errors.New("Can't work with 42")
}
// A nil value in the error position indicates that there was no error.
return arg + 3, nil
}
// It’s possible to use custom types as errors by implementing the Error() method on them.
// Here’s a variant on the example above that uses a custom type to explicitly represent an argument error.
type argError struct {
arg int
prob string
}
func (e *argError) Error() string {
return fmt.Sprintf("%d - %s", e.arg, e.prob)
}
func f2(arg int) (int, error) {
if arg == 42 {
// In this case we use &argError syntax to build a new struct,
// supplying values for the two fields arg and prob.
return -1, &argError{arg, "Can't work with 42"}
}
return arg + 3, nil
}
// Errors describe function
func Errors() {
// The two loops below test out each of our error-returning functions.
// Note that the use of an inline error check on the if line is a common idiom in Go code.
for _, i := range []int{7, 42} {
if r, e := f1(i); e != nil {
fmt.Println("f1 failed: ", e)
} else {
fmt.Println("f1 worked: ", r)
}
}
for _, i := range []int{7, 42} {
if r, e := f2(i); e != nil {
fmt.Println("f2 failed: ", e)
} else {
fmt.Println("f2 worked: ", r)
}
}
// If you want to programmatically use the data in a custom error,
// you’ll need to get the error as an instance of the custom error type via type assertion.
_, e := f2(42)
if ae, ok := e.(*argError); ok {
fmt.Println(ae.arg)
fmt.Println(ae.prob)
}
}