forked from steger/pr3-sose2026
63 lines
1.6 KiB
Go
63 lines
1.6 KiB
Go
package main
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
)
|
|
|
|
// a function that can fail, so it returns an error as the second return value
|
|
func f(arg int) (int, error) {
|
|
if arg == 42 {
|
|
// in case of an error, return the zero value for the result and a non-nil error
|
|
return 0, errors.New("can't work with 42")
|
|
}
|
|
|
|
// simply return the result and a nil error in the success case
|
|
return arg + 3, nil
|
|
}
|
|
|
|
// define some errors to use in makeTea
|
|
var ErrOutOfTea = fmt.Errorf("no more tea available")
|
|
var ErrPower = fmt.Errorf("can't boil water")
|
|
|
|
// a function that can fail in multiple ways, so it returns an error as the second return value
|
|
func makeTea(arg int) error {
|
|
if arg == 2 {
|
|
// return the error directly, so we can check for it later with errors.Is
|
|
return ErrOutOfTea
|
|
} else if arg == 4 {
|
|
// use %w to wrap the error, so we can check for it later with errors.Is
|
|
return fmt.Errorf("making tea: %w", ErrPower)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func main() {
|
|
for _, i := range []int{7, 42} {
|
|
|
|
//typical pattern for checking errors in Go: if the error is not nil, handle it and return or continue; otherwise, use the result
|
|
if r, e := f(i); e != nil {
|
|
fmt.Println("f failed:", e)
|
|
} else {
|
|
fmt.Println("f worked:", r)
|
|
}
|
|
}
|
|
|
|
for i := range 5 {
|
|
if err := makeTea(i); err != nil {
|
|
|
|
// use errors.Is to check for specific errors, even if they are wrapped
|
|
if errors.Is(err, ErrOutOfTea) {
|
|
fmt.Println("We should buy new tea!")
|
|
} else if errors.Is(err, ErrPower) { // this error is wrapped, but errors.Is can still check for it
|
|
fmt.Println("Now it is dark.")
|
|
} else {
|
|
fmt.Printf("unknown error: %s\n", err)
|
|
}
|
|
continue
|
|
}
|
|
|
|
fmt.Println("Tea is ready!")
|
|
}
|
|
}
|