diff --git a/CHANGELOG.md b/CHANGELOG.md index 726e7013..a8b8ed27 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,13 @@ @samber: I sometimes forget to update this file. Ping me on [Twitter](https://twitter.com/samuelberthe) or open an issue in case of error. We need to keep a clear changelog for easier lib upgrade. +## 1.30.1 (2022-10-06) + +Fix: + +- lo.Try1: remove generic type +- lo.Validate: format error properly + ## 1.30.0 (2022-10-04) Adding: diff --git a/README.md b/README.md index 4b90a5fe..7c27c02b 100644 --- a/README.md +++ b/README.md @@ -1137,14 +1137,16 @@ sub := len("hellô") Creates a tuple from a list of values. ```go -tuple1 := lo.T2[string, int]("x", 1) +tuple1 := lo.T2("x", 1) // Tuple2[string, int]{A: "x", B: 1} func example() (string, int) { return "y", 2 } -tuple2 := lo.T2[string, int](example()) +tuple2 := lo.T2(example()) // Tuple2[string, int]{A: "y", B: 2} ``` +[[play](https://go.dev/play/p/IllL3ZO4BQm)] + ### Unpack2 -> Unpack9 Returns values contained in tuple. @@ -1154,6 +1156,8 @@ r1, r2 := lo.Unpack2[string, int](lo.Tuple2[string, int]{"a", 1}) // "a", 1 ``` +[[play](https://go.dev/play/p/xVP_k0kJ96W)] + ### Zip2 -> Zip9 Zip creates a slice of grouped elements, the first of which contains the first elements of the given arrays, the second of which contains the second elements of the given arrays, and so on. @@ -1165,6 +1169,8 @@ tuples := lo.Zip2[string, int]([]string{"a", "b"}, []int{1, 2}) // []Tuple2[string, int]{{A: "a", B: 1}, {A: "b", B: 2}} ``` +[[play](https://go.dev/play/p/jujaA6GaJTp)] + ### Unzip2 -> Unzip9 Unzip accepts an array of grouped elements and creates an array regrouping the elements to their pre-zip configuration. @@ -1175,6 +1181,8 @@ a, b := lo.Unzip2[string, int]([]Tuple2[string, int]{{A: "a", B: 1}, {A: "b", B: // []int{1, 2} ``` +[[play](https://go.dev/play/p/ciHugugvaAW)] + ### ChannelDispatcher Distributes messages from input channels into N child channels. Close events are propagated to children. @@ -1982,6 +1990,8 @@ iter, err := lo.Attempt(0, func(i int) error { For more advanced retry strategies (delay, exponential backoff...), please take a look on [cenkalti/backoff](https://github.com/cenkalti/backoff). +[[play](https://go.dev/play/p/3ggJZ2ZKcMj)] + ### AttemptWithDelay Invokes a function N times until it returns valid output, with a pause between each call. Returning either the caught error or nil. @@ -2003,6 +2013,8 @@ iter, duration, err := lo.AttemptWithDelay(5, 2*time.Second, func(i int, duratio For more advanced retry strategies (delay, exponential backoff...), please take a look on [cenkalti/backoff](https://github.com/cenkalti/backoff). +[[play](https://go.dev/play/p/tVs6CygC7m1)] + ### Debounce `NewDebounce` creates a debounced instance that delays invoking functions given until after wait milliseconds have elapsed, until `cancel` is called. @@ -2021,6 +2033,8 @@ time.Sleep(1 * time.Second) cancel() ``` +[[play](https://go.dev/play/p/mz32VMK2nqe)] + ### Synchronize Wraps the underlying callback in a mutex. It receives an optional mutex. @@ -2094,6 +2108,8 @@ val := lo.Validate(len(slice) == 0, "Slice should be empty but contains %v", sli // nil ``` +[[play](https://go.dev/play/p/vPyh51XpCBt)] + ### Must Wraps a function call to panics if second argument is `error` or `false`, returns the value otherwise. @@ -2106,6 +2122,8 @@ val := lo.Must(time.Parse("2006-01-02", "bad-value")) // panics ``` +[[play](https://go.dev/play/p/TMoWrRp3DyC)] + ### Must{0->6} Must\* has the same behavior than Must, but returns multiple values. @@ -2152,6 +2170,8 @@ lo.Must0(lo.Contains[int](list, item), "'%s' must always contain '%s'", list, it ... ``` +[[play](https://go.dev/play/p/TMoWrRp3DyC)] + ### Try Calls the function and return false in case of error and on panic. @@ -2174,6 +2194,8 @@ ok := lo.Try(func() error { // false ``` +[[play](https://go.dev/play/p/mTyyWUvn9u4)] + ### Try{0->6} The same behavior than `Try`, but callback returns 2 variables. @@ -2186,6 +2208,8 @@ ok := lo.Try2(func() (string, error) { // false ``` +[[play](https://go.dev/play/p/mTyyWUvn9u4)] + ### TryOr Calls the function and return a default value in case of error and on panic. @@ -2211,6 +2235,8 @@ ok := lo.TryOr(func() error { // false ``` +[[play](https://go.dev/play/p/B4F7Wg2Zh9X)] + ### TryOr{0->6} The same behavior than `TryOr`, but callback returns 2 variables. @@ -2225,6 +2251,8 @@ str, nbr, ok := lo.TryOr2(func() (string, int, error) { // false ``` +[[play](https://go.dev/play/p/B4F7Wg2Zh9X)] + ### TryWithErrorValue The same behavior than `Try`, but also returns value passed to panic. @@ -2237,6 +2265,8 @@ err, ok := lo.TryWithErrorValue(func() error { // "error", false ``` +[[play](https://go.dev/play/p/Kc7afQIT2Fs)] + ### TryCatch The same behavior than `Try`, but calls the catch function in case of error. @@ -2254,6 +2284,8 @@ ok := lo.TryCatch(func() error { // caught == true ``` +[[play](https://go.dev/play/p/PnOON-EqBiU)] + ### TryCatchWithErrorValue The same behavior than `TryWithErrorValue`, but calls the catch function in case of error. @@ -2271,6 +2303,8 @@ ok := lo.TryCatchWithErrorValue(func() error { // caught == true ``` +[[play](https://go.dev/play/p/8Pc9gwX_GZO)] + ### ErrorsAs A shortcut for: @@ -2294,6 +2328,8 @@ if rateLimitErr, ok := lo.ErrorsAs[*RateLimitError](err); ok { } ``` +[[play](https://go.dev/play/p/8wk5rH8UfrE)] + ## 🛩 Benchmark We executed a simple benchmark with the a dead-simple `lo.Map` loop: diff --git a/errors.go b/errors.go index efc4d9e8..f2e9338e 100644 --- a/errors.go +++ b/errors.go @@ -7,9 +7,10 @@ import ( ) // Validate is a helper that creates an error when a condition is not met. +// Play: https://go.dev/play/p/vPyh51XpCBt func Validate(ok bool, format string, args ...any) error { if !ok { - return errors.New(fmt.Sprint(format, args)) + return errors.New(fmt.Sprintf(format, args...)) } return nil } @@ -59,46 +60,54 @@ func must(err any, messageArgs ...interface{}) { // Must is a helper that wraps a call to a function returning a value and an error // and panics if err is error or false. +// Play: https://go.dev/play/p/TMoWrRp3DyC func Must[T any](val T, err any, messageArgs ...interface{}) T { must(err, messageArgs...) return val } // Must0 has the same behavior than Must, but callback returns no variable. +// Play: https://go.dev/play/p/TMoWrRp3DyC func Must0(err any, messageArgs ...interface{}) { must(err, messageArgs...) } // Must1 is an alias to Must +// Play: https://go.dev/play/p/TMoWrRp3DyC func Must1[T any](val T, err any, messageArgs ...interface{}) T { return Must(val, err, messageArgs...) } // Must2 has the same behavior than Must, but callback returns 2 variables. +// Play: https://go.dev/play/p/TMoWrRp3DyC func Must2[T1 any, T2 any](val1 T1, val2 T2, err any, messageArgs ...interface{}) (T1, T2) { must(err, messageArgs...) return val1, val2 } // Must3 has the same behavior than Must, but callback returns 3 variables. +// Play: https://go.dev/play/p/TMoWrRp3DyC func Must3[T1 any, T2 any, T3 any](val1 T1, val2 T2, val3 T3, err any, messageArgs ...interface{}) (T1, T2, T3) { must(err, messageArgs...) return val1, val2, val3 } // Must4 has the same behavior than Must, but callback returns 4 variables. +// Play: https://go.dev/play/p/TMoWrRp3DyC func Must4[T1 any, T2 any, T3 any, T4 any](val1 T1, val2 T2, val3 T3, val4 T4, err any, messageArgs ...interface{}) (T1, T2, T3, T4) { must(err, messageArgs...) return val1, val2, val3, val4 } // Must5 has the same behavior than Must, but callback returns 5 variables. +// Play: https://go.dev/play/p/TMoWrRp3DyC func Must5[T1 any, T2 any, T3 any, T4 any, T5 any](val1 T1, val2 T2, val3 T3, val4 T4, val5 T5, err any, messageArgs ...interface{}) (T1, T2, T3, T4, T5) { must(err, messageArgs...) return val1, val2, val3, val4, val5 } // Must6 has the same behavior than Must, but callback returns 6 variables. +// Play: https://go.dev/play/p/TMoWrRp3DyC func Must6[T1 any, T2 any, T3 any, T4 any, T5 any, T6 any](val1 T1, val2 T2, val3 T3, val4 T4, val5 T5, val6 T6, err any, messageArgs ...interface{}) (T1, T2, T3, T4, T5, T6) { must(err, messageArgs...) return val1, val2, val3, val4, val5, val6 @@ -123,6 +132,7 @@ func Try(callback func() error) (ok bool) { } // Try0 has the same behavior than Try, but callback returns no variable. +// Play: https://go.dev/play/p/mTyyWUvn9u4 func Try0(callback func()) bool { return Try(func() error { callback() @@ -131,11 +141,13 @@ func Try0(callback func()) bool { } // Try1 is an alias to Try. -func Try1[T any](callback func() error) bool { +// Play: https://go.dev/play/p/mTyyWUvn9u4 +func Try1(callback func() error) bool { return Try(callback) } // Try2 has the same behavior than Try, but callback returns 2 variables. +// Play: https://go.dev/play/p/mTyyWUvn9u4 func Try2[T any](callback func() (T, error)) bool { return Try(func() error { _, err := callback() @@ -144,6 +156,7 @@ func Try2[T any](callback func() (T, error)) bool { } // Try3 has the same behavior than Try, but callback returns 3 variables. +// Play: https://go.dev/play/p/mTyyWUvn9u4 func Try3[T, R any](callback func() (T, R, error)) bool { return Try(func() error { _, _, err := callback() @@ -152,6 +165,7 @@ func Try3[T, R any](callback func() (T, R, error)) bool { } // Try4 has the same behavior than Try, but callback returns 4 variables. +// Play: https://go.dev/play/p/mTyyWUvn9u4 func Try4[T, R, S any](callback func() (T, R, S, error)) bool { return Try(func() error { _, _, _, err := callback() @@ -160,6 +174,7 @@ func Try4[T, R, S any](callback func() (T, R, S, error)) bool { } // Try5 has the same behavior than Try, but callback returns 5 variables. +// Play: https://go.dev/play/p/mTyyWUvn9u4 func Try5[T, R, S, Q any](callback func() (T, R, S, Q, error)) bool { return Try(func() error { _, _, _, _, err := callback() @@ -168,6 +183,7 @@ func Try5[T, R, S, Q any](callback func() (T, R, S, Q, error)) bool { } // Try6 has the same behavior than Try, but callback returns 6 variables. +// Play: https://go.dev/play/p/mTyyWUvn9u4 func Try6[T, R, S, Q, U any](callback func() (T, R, S, Q, U, error)) bool { return Try(func() error { _, _, _, _, _, err := callback() @@ -176,11 +192,13 @@ func Try6[T, R, S, Q, U any](callback func() (T, R, S, Q, U, error)) bool { } // TryOr has the same behavior than Must, but returns a default value in case of error. +// Play: https://go.dev/play/p/B4F7Wg2Zh9X func TryOr[A any](callback func() (A, error), fallbackA A) (A, bool) { return TryOr1(callback, fallbackA) } // TryOr1 has the same behavior than Must, but returns a default value in case of error. +// Play: https://go.dev/play/p/B4F7Wg2Zh9X func TryOr1[A any](callback func() (A, error), fallbackA A) (A, bool) { ok := false @@ -196,6 +214,7 @@ func TryOr1[A any](callback func() (A, error), fallbackA A) (A, bool) { } // TryOr2 has the same behavior than Must, but returns a default value in case of error. +// Play: https://go.dev/play/p/B4F7Wg2Zh9X func TryOr2[A any, B any](callback func() (A, B, error), fallbackA A, fallbackB B) (A, B, bool) { ok := false @@ -212,6 +231,7 @@ func TryOr2[A any, B any](callback func() (A, B, error), fallbackA A, fallbackB } // TryOr3 has the same behavior than Must, but returns a default value in case of error. +// Play: https://go.dev/play/p/B4F7Wg2Zh9X func TryOr3[A any, B any, C any](callback func() (A, B, C, error), fallbackA A, fallbackB B, fallbackC C) (A, B, C, bool) { ok := false @@ -229,6 +249,7 @@ func TryOr3[A any, B any, C any](callback func() (A, B, C, error), fallbackA A, } // TryOr4 has the same behavior than Must, but returns a default value in case of error. +// Play: https://go.dev/play/p/B4F7Wg2Zh9X func TryOr4[A any, B any, C any, D any](callback func() (A, B, C, D, error), fallbackA A, fallbackB B, fallbackC C, fallbackD D) (A, B, C, D, bool) { ok := false @@ -247,6 +268,7 @@ func TryOr4[A any, B any, C any, D any](callback func() (A, B, C, D, error), fal } // TryOr5 has the same behavior than Must, but returns a default value in case of error. +// Play: https://go.dev/play/p/B4F7Wg2Zh9X func TryOr5[A any, B any, C any, D any, E any](callback func() (A, B, C, D, E, error), fallbackA A, fallbackB B, fallbackC C, fallbackD D, fallbackE E) (A, B, C, D, E, bool) { ok := false @@ -266,6 +288,7 @@ func TryOr5[A any, B any, C any, D any, E any](callback func() (A, B, C, D, E, e } // TryOr6 has the same behavior than Must, but returns a default value in case of error. +// Play: https://go.dev/play/p/B4F7Wg2Zh9X func TryOr6[A any, B any, C any, D any, E any, F any](callback func() (A, B, C, D, E, F, error), fallbackA A, fallbackB B, fallbackC C, fallbackD D, fallbackE E, fallbackF F) (A, B, C, D, E, F, bool) { ok := false @@ -286,6 +309,7 @@ func TryOr6[A any, B any, C any, D any, E any, F any](callback func() (A, B, C, } // TryWithErrorValue has the same behavior than Try, but also returns value passed to panic. +// Play: https://go.dev/play/p/Kc7afQIT2Fs func TryWithErrorValue(callback func() error) (errorValue any, ok bool) { ok = true @@ -306,6 +330,7 @@ func TryWithErrorValue(callback func() error) (errorValue any, ok bool) { } // TryCatch has the same behavior than Try, but calls the catch function in case of error. +// Play: https://go.dev/play/p/PnOON-EqBiU func TryCatch(callback func() error, catch func()) { if !Try(callback) { catch() @@ -313,6 +338,7 @@ func TryCatch(callback func() error, catch func()) { } // TryCatchWithErrorValue has the same behavior than TryWithErrorValue, but calls the catch function in case of error. +// Play: https://go.dev/play/p/8Pc9gwX_GZO func TryCatchWithErrorValue(callback func() error, catch func(any)) { if err, ok := TryWithErrorValue(callback); !ok { catch(err) @@ -320,6 +346,7 @@ func TryCatchWithErrorValue(callback func() error, catch func(any)) { } // ErrorsAs is a shortcut for errors.As(err, &&T). +// Play: https://go.dev/play/p/8wk5rH8UfrE func ErrorsAs[T error](err error) (T, bool) { var t T ok := errors.As(err, &t) diff --git a/errors_example_test.go b/errors_example_test.go new file mode 100644 index 00000000..056feab8 --- /dev/null +++ b/errors_example_test.go @@ -0,0 +1,444 @@ +package lo + +import ( + "fmt" +) + +func ExampleValidate() { + i := 42 + + err1 := Validate(i < 0, "expected %d < 0", i) + err2 := Validate(i > 0, "expected %d > 0", i) + + fmt.Printf("%v\n%v", err1, err2) + // Output: + // expected 42 < 0 + // +} + +func ExampleMust() { + defer func() { + recover() + }() + + // won't panic + Must(42, nil) + + // won't panic + cb := func() (int, error) { + return 42, nil + } + Must(cb()) + + // will panic + Must(42, fmt.Errorf("my error")) + + // will panic with error message + Must(42, fmt.Errorf("world"), "hello") +} + +func ExampleMust0() { + defer func() { + recover() + }() + + // won't panic + Must0(nil) + + // will panic + Must0(fmt.Errorf("my error")) + + // will panic with error message + Must0(fmt.Errorf("world"), "hello") +} + +func ExampleMust1() { + defer func() { + recover() + }() + + // won't panic + Must1(42, nil) + + // won't panic + cb := func() (int, error) { + return 42, nil + } + Must1(cb()) + + // will panic + Must1(42, fmt.Errorf("my error")) + + // will panic with error message + Must1(42, fmt.Errorf("world"), "hello") +} + +func ExampleMust2() { + defer func() { + recover() + }() + + // won't panic + Must2(42, "hello", nil) + + // will panic + Must2(42, "hello", fmt.Errorf("my error")) + + // will panic with error message + Must2(42, "hello", fmt.Errorf("world"), "hello") +} + +func ExampleMust3() { + defer func() { + recover() + }() + + // won't panic + Must3(42, "hello", 4.2, nil) + + // will panic + Must3(42, "hello", 4.2, fmt.Errorf("my error")) + + // will panic with error message + Must3(42, "hello", 4.2, fmt.Errorf("world"), "hello") +} + +func ExampleMust4() { + defer func() { + recover() + }() + + // won't panic + Must4(42, "hello", 4.2, true, nil) + + // will panic + Must4(42, "hello", 4.2, true, fmt.Errorf("my error")) + + // will panic with error message + Must4(42, "hello", 4.2, true, fmt.Errorf("world"), "hello") +} + +func ExampleMust5() { + defer func() { + recover() + }() + + // won't panic + Must5(42, "hello", 4.2, true, foo{}, nil) + + // will panic + Must5(42, "hello", 4.2, true, foo{}, fmt.Errorf("my error")) + + // will panic with error message + Must5(42, "hello", 4.2, true, foo{}, fmt.Errorf("world"), "hello") +} + +func ExampleMust6() { + defer func() { + recover() + }() + + // won't panic + Must5(42, "hello", 4.2, true, foo{}, "foobar", nil) + + // will panic + Must5(42, "hello", 4.2, true, foo{}, "foobar", fmt.Errorf("my error")) + + // will panic with error message + Must5(42, "hello", 4.2, true, foo{}, "foobar", fmt.Errorf("world"), "hello") +} + +func ExampleTry() { + ok1 := Try(func() error { + return nil + }) + ok2 := Try(func() error { + return fmt.Errorf("my error") + }) + ok3 := Try(func() error { + panic("my error") + return nil + }) + + fmt.Printf("%v\n", ok1) + fmt.Printf("%v\n", ok2) + fmt.Printf("%v\n", ok3) + // Output: + // true + // false + // false +} + +func ExampleTry1() { + ok1 := Try1(func() error { + return nil + }) + ok2 := Try1(func() error { + return fmt.Errorf("my error") + }) + ok3 := Try1(func() error { + panic("my error") + return nil + }) + + fmt.Printf("%v\n", ok1) + fmt.Printf("%v\n", ok2) + fmt.Printf("%v\n", ok3) + // Output: + // true + // false + // false +} + +func ExampleTry2() { + ok1 := Try2(func() (int, error) { + return 42, nil + }) + ok2 := Try2(func() (int, error) { + return 42, fmt.Errorf("my error") + }) + ok3 := Try2(func() (int, error) { + panic("my error") + return 42, nil + }) + + fmt.Printf("%v\n", ok1) + fmt.Printf("%v\n", ok2) + fmt.Printf("%v\n", ok3) + // Output: + // true + // false + // false +} + +func ExampleTry3() { + ok1 := Try3(func() (int, string, error) { + return 42, "foobar", nil + }) + ok2 := Try3(func() (int, string, error) { + return 42, "foobar", fmt.Errorf("my error") + }) + ok3 := Try3(func() (int, string, error) { + panic("my error") + return 42, "foobar", nil + }) + + fmt.Printf("%v\n", ok1) + fmt.Printf("%v\n", ok2) + fmt.Printf("%v\n", ok3) + // Output: + // true + // false + // false +} + +func ExampleTry4() { + ok1 := Try4(func() (int, string, float64, error) { + return 42, "foobar", 4.2, nil + }) + ok2 := Try4(func() (int, string, float64, error) { + return 42, "foobar", 4.2, fmt.Errorf("my error") + }) + ok3 := Try4(func() (int, string, float64, error) { + panic("my error") + return 42, "foobar", 4.2, nil + }) + + fmt.Printf("%v\n", ok1) + fmt.Printf("%v\n", ok2) + fmt.Printf("%v\n", ok3) + // Output: + // true + // false + // false +} + +func ExampleTry5() { + ok1 := Try5(func() (int, string, float64, bool, error) { + return 42, "foobar", 4.2, true, nil + }) + ok2 := Try5(func() (int, string, float64, bool, error) { + return 42, "foobar", 4.2, true, fmt.Errorf("my error") + }) + ok3 := Try5(func() (int, string, float64, bool, error) { + panic("my error") + return 42, "foobar", 4.2, true, nil + }) + + fmt.Printf("%v\n", ok1) + fmt.Printf("%v\n", ok2) + fmt.Printf("%v\n", ok3) + // Output: + // true + // false + // false +} + +func ExampleTry6() { + ok1 := Try6(func() (int, string, float64, bool, foo, error) { + return 42, "foobar", 4.2, true, foo{}, nil + }) + ok2 := Try6(func() (int, string, float64, bool, foo, error) { + return 42, "foobar", 4.2, true, foo{}, fmt.Errorf("my error") + }) + ok3 := Try6(func() (int, string, float64, bool, foo, error) { + panic("my error") + return 42, "foobar", 4.2, true, foo{}, nil + }) + + fmt.Printf("%v\n", ok1) + fmt.Printf("%v\n", ok2) + fmt.Printf("%v\n", ok3) + // Output: + // true + // false + // false +} + +func ExampleTryOr() { + value1, ok1 := TryOr(func() (int, error) { + return 42, nil + }, 21) + value2, ok2 := TryOr(func() (int, error) { + return 42, fmt.Errorf("my error") + }, 21) + value3, ok3 := TryOr(func() (int, error) { + panic("my error") + return 42, nil + }, 21) + + fmt.Printf("%v %v\n", value1, ok1) + fmt.Printf("%v %v\n", value2, ok2) + fmt.Printf("%v %v\n", value3, ok3) + // Output: + // 42 true + // 21 false + // 21 false +} + +func ExampleTryOr1() { + value1, ok1 := TryOr1(func() (int, error) { + return 42, nil + }, 21) + value2, ok2 := TryOr1(func() (int, error) { + return 42, fmt.Errorf("my error") + }, 21) + value3, ok3 := TryOr1(func() (int, error) { + panic("my error") + return 42, nil + }, 21) + + fmt.Printf("%v %v\n", value1, ok1) + fmt.Printf("%v %v\n", value2, ok2) + fmt.Printf("%v %v\n", value3, ok3) + // Output: + // 42 true + // 21 false + // 21 false +} + +func ExampleTryOr2() { + value1, value2, ok3 := TryOr2(func() (int, string, error) { + panic("my error") + return 42, "world", nil + }, 21, "hello") + + fmt.Printf("%v %v %v\n", value1, value2, ok3) + // Output: 21 hello false +} + +func ExampleTryOr3() { + value1, value2, value3, ok3 := TryOr3(func() (int, string, bool, error) { + panic("my error") + return 42, "world", true, nil + }, 21, "hello", false) + + fmt.Printf("%v %v %v %v\n", value1, value2, value3, ok3) + // Output: 21 hello false false +} + +func ExampleTryOr4() { + value1, value2, value3, value4, ok3 := TryOr4(func() (int, string, bool, foo, error) { + panic("my error") + return 42, "world", true, foo{bar: "baz"}, nil + }, 21, "hello", false, foo{bar: "bar"}) + + fmt.Printf("%v %v %v %v %v\n", value1, value2, value3, value4, ok3) + // Output: 21 hello false {bar} false +} + +func ExampleTryOr5() { + value1, value2, value3, value4, value5, ok3 := TryOr5(func() (int, string, bool, foo, float64, error) { + panic("my error") + return 42, "world", true, foo{bar: "baz"}, 4.2, nil + }, 21, "hello", false, foo{bar: "bar"}, 4.2) + + fmt.Printf("%v %v %v %v %v %v\n", value1, value2, value3, value4, value5, ok3) + // Output: 21 hello false {bar} 4.2 false +} +func ExampleTryOr6() { + value1, value2, value3, value4, value5, value6, ok3 := TryOr6(func() (int, string, bool, foo, float64, string, error) { + panic("my error") + return 42, "world", true, foo{bar: "baz"}, 4.2, "hello", nil + }, 21, "hello", false, foo{bar: "bar"}, 4.2, "world") + + fmt.Printf("%v %v %v %v %v %v %v\n", value1, value2, value3, value4, value5, value6, ok3) + // Output: 21 hello false {bar} 4.2 world false +} + +func ExampleTryWithErrorValue() { + err1, ok1 := TryWithErrorValue(func() error { + return nil + }) + err2, ok2 := TryWithErrorValue(func() error { + return fmt.Errorf("my error") + }) + err3, ok3 := TryWithErrorValue(func() error { + panic("my error") + return nil + }) + + fmt.Printf("%v %v\n", err1, ok1) + fmt.Printf("%v %v\n", err2, ok2) + fmt.Printf("%v %v\n", err3, ok3) + // Output: + // true + // my error false + // my error false +} + +func ExampleTryCatchWithErrorValue() { + TryCatchWithErrorValue( + func() error { + panic("trigger an error") + }, + func(err any) { + fmt.Printf("catch: %s", err) + }, + ) + + // Output: catch: trigger an error +} + +type myError struct { +} + +func (e myError) Error() string { + return "my error" +} + +func ExampleErrorsAs() { + doSomething := func() error { + return &myError{} + } + + err := doSomething() + + if rateLimitErr, ok := ErrorsAs[*myError](err); ok { + fmt.Printf("is type myError, err: %s", rateLimitErr.Error()) + } else { + fmt.Printf("is not type myError") + } + + // Output: is type myError, err: my error +} diff --git a/retry.go b/retry.go index d4c4a98f..b4a61efb 100644 --- a/retry.go +++ b/retry.go @@ -46,6 +46,7 @@ func (d *debounce) cancel() { } // NewDebounce creates a debounced instance that delays invoking functions given until after wait milliseconds have elapsed. +// Play: https://go.dev/play/p/mz32VMK2nqe func NewDebounce(duration time.Duration, f ...func()) (func(), func()) { d := &debounce{ after: duration, @@ -61,6 +62,7 @@ func NewDebounce(duration time.Duration, f ...func()) (func(), func()) { } // Attempt invokes a function N times until it returns valid output. Returning either the caught error or nil. When first argument is less than `1`, the function runs until a successful response is returned. +// Play: https://go.dev/play/p/3ggJZ2ZKcMj func Attempt(maxIteration int, f func(int) error) (int, error) { var err error @@ -79,6 +81,7 @@ func Attempt(maxIteration int, f func(int) error) (int, error) { // with a pause between each call. Returning either the caught error or nil. // When first argument is less than `1`, the function runs until a successful // response is returned. +// Play: https://go.dev/play/p/tVs6CygC7m1 func AttemptWithDelay(maxIteration int, delay time.Duration, f func(int, time.Duration) error) (int, time.Duration, error) { var err error diff --git a/retry_example_test.go b/retry_example_test.go new file mode 100644 index 00000000..cd4e18cb --- /dev/null +++ b/retry_example_test.go @@ -0,0 +1,82 @@ +package lo + +import ( + "fmt" + "time" +) + +func ExampleNewDebounce() { + i := 0 + calls := []int{} + + debounce, cancel := NewDebounce(time.Millisecond, func() { + calls = append(calls, i) + }) + + debounce() + i++ + + time.Sleep(5 * time.Millisecond) + + debounce() + i++ + debounce() + i++ + debounce() + i++ + + time.Sleep(5 * time.Millisecond) + + cancel() + + fmt.Printf("%v", calls) + // Output: [1 4] +} + +func ExampleAttempt() { + count1, err1 := Attempt(2, func(i int) error { + if i == 0 { + return fmt.Errorf("error") + } + + return nil + }) + + count2, err2 := Attempt(2, func(i int) error { + if i < 10 { + return fmt.Errorf("error") + } + + return nil + }) + + fmt.Printf("%v %v\n", count1, err1) + fmt.Printf("%v %v\n", count2, err2) + // Output: + // 2 + // 2 error +} + +func ExampleAttemptWithDelay() { + count1, time1, err1 := AttemptWithDelay(2, time.Millisecond, func(i int, _ time.Duration) error { + if i == 0 { + return fmt.Errorf("error") + } + + return nil + }) + + count2, time2, err2 := AttemptWithDelay(2, time.Millisecond, func(i int, _ time.Duration) error { + if i < 10 { + return fmt.Errorf("error") + } + + return nil + }) + + fmt.Printf("%v %v %v\n", count1, time1.Truncate(time.Millisecond), err1) + fmt.Printf("%v %v %v\n", count2, time2.Truncate(time.Millisecond), err2) + // Output: + // 2 1ms + // 2 1ms error +} diff --git a/tuples.go b/tuples.go index 0f0a7569..f8ea2f14 100644 --- a/tuples.go +++ b/tuples.go @@ -1,81 +1,97 @@ package lo // T2 creates a tuple from a list of values. +// Play: https://go.dev/play/p/IllL3ZO4BQm func T2[A any, B any](a A, b B) Tuple2[A, B] { return Tuple2[A, B]{A: a, B: b} } // T3 creates a tuple from a list of values. +// Play: https://go.dev/play/p/IllL3ZO4BQm func T3[A any, B any, C any](a A, b B, c C) Tuple3[A, B, C] { return Tuple3[A, B, C]{A: a, B: b, C: c} } // T4 creates a tuple from a list of values. +// Play: https://go.dev/play/p/IllL3ZO4BQm func T4[A any, B any, C any, D any](a A, b B, c C, d D) Tuple4[A, B, C, D] { return Tuple4[A, B, C, D]{A: a, B: b, C: c, D: d} } // T5 creates a tuple from a list of values. +// Play: https://go.dev/play/p/IllL3ZO4BQm func T5[A any, B any, C any, D any, E any](a A, b B, c C, d D, e E) Tuple5[A, B, C, D, E] { return Tuple5[A, B, C, D, E]{A: a, B: b, C: c, D: d, E: e} } // T6 creates a tuple from a list of values. +// Play: https://go.dev/play/p/IllL3ZO4BQm func T6[A any, B any, C any, D any, E any, F any](a A, b B, c C, d D, e E, f F) Tuple6[A, B, C, D, E, F] { return Tuple6[A, B, C, D, E, F]{A: a, B: b, C: c, D: d, E: e, F: f} } // T7 creates a tuple from a list of values. +// Play: https://go.dev/play/p/IllL3ZO4BQm func T7[A any, B any, C any, D any, E any, F any, G any](a A, b B, c C, d D, e E, f F, g G) Tuple7[A, B, C, D, E, F, G] { return Tuple7[A, B, C, D, E, F, G]{A: a, B: b, C: c, D: d, E: e, F: f, G: g} } // T8 creates a tuple from a list of values. +// Play: https://go.dev/play/p/IllL3ZO4BQm func T8[A any, B any, C any, D any, E any, F any, G any, H any](a A, b B, c C, d D, e E, f F, g G, h H) Tuple8[A, B, C, D, E, F, G, H] { return Tuple8[A, B, C, D, E, F, G, H]{A: a, B: b, C: c, D: d, E: e, F: f, G: g, H: h} } // T8 creates a tuple from a list of values. +// Play: https://go.dev/play/p/IllL3ZO4BQm func T9[A any, B any, C any, D any, E any, F any, G any, H any, I any](a A, b B, c C, d D, e E, f F, g G, h H, i I) Tuple9[A, B, C, D, E, F, G, H, I] { return Tuple9[A, B, C, D, E, F, G, H, I]{A: a, B: b, C: c, D: d, E: e, F: f, G: g, H: h, I: i} } // Unpack2 returns values contained in tuple. +// Play: https://go.dev/play/p/xVP_k0kJ96W func Unpack2[A any, B any](tuple Tuple2[A, B]) (A, B) { return tuple.A, tuple.B } // Unpack3 returns values contained in tuple. +// Play: https://go.dev/play/p/xVP_k0kJ96W func Unpack3[A any, B any, C any](tuple Tuple3[A, B, C]) (A, B, C) { return tuple.A, tuple.B, tuple.C } // Unpack4 returns values contained in tuple. +// Play: https://go.dev/play/p/xVP_k0kJ96W func Unpack4[A any, B any, C any, D any](tuple Tuple4[A, B, C, D]) (A, B, C, D) { return tuple.A, tuple.B, tuple.C, tuple.D } // Unpack5 returns values contained in tuple. +// Play: https://go.dev/play/p/xVP_k0kJ96W func Unpack5[A any, B any, C any, D any, E any](tuple Tuple5[A, B, C, D, E]) (A, B, C, D, E) { return tuple.A, tuple.B, tuple.C, tuple.D, tuple.E } // Unpack6 returns values contained in tuple. +// Play: https://go.dev/play/p/xVP_k0kJ96W func Unpack6[A any, B any, C any, D any, E any, F any](tuple Tuple6[A, B, C, D, E, F]) (A, B, C, D, E, F) { return tuple.A, tuple.B, tuple.C, tuple.D, tuple.E, tuple.F } // Unpack7 returns values contained in tuple. +// Play: https://go.dev/play/p/xVP_k0kJ96W func Unpack7[A any, B any, C any, D any, E any, F any, G any](tuple Tuple7[A, B, C, D, E, F, G]) (A, B, C, D, E, F, G) { return tuple.A, tuple.B, tuple.C, tuple.D, tuple.E, tuple.F, tuple.G } // Unpack8 returns values contained in tuple. +// Play: https://go.dev/play/p/xVP_k0kJ96W func Unpack8[A any, B any, C any, D any, E any, F any, G any, H any](tuple Tuple8[A, B, C, D, E, F, G, H]) (A, B, C, D, E, F, G, H) { return tuple.A, tuple.B, tuple.C, tuple.D, tuple.E, tuple.F, tuple.G, tuple.H } // Unpack9 returns values contained in tuple. +// Play: https://go.dev/play/p/xVP_k0kJ96W func Unpack9[A any, B any, C any, D any, E any, F any, G any, H any, I any](tuple Tuple9[A, B, C, D, E, F, G, H, I]) (A, B, C, D, E, F, G, H, I) { return tuple.A, tuple.B, tuple.C, tuple.D, tuple.E, tuple.F, tuple.G, tuple.H, tuple.I } @@ -83,6 +99,7 @@ func Unpack9[A any, B any, C any, D any, E any, F any, G any, H any, I any](tupl // Zip2 creates a slice of grouped elements, the first of which contains the first elements // of the given arrays, the second of which contains the second elements of the given arrays, and so on. // When collections have different size, the Tuple attributes are filled with zero value. +// Play: https://go.dev/play/p/jujaA6GaJTp func Zip2[A any, B any](a []A, b []B) []Tuple2[A, B] { size := Max([]int{len(a), len(b)}) @@ -104,6 +121,7 @@ func Zip2[A any, B any](a []A, b []B) []Tuple2[A, B] { // Zip3 creates a slice of grouped elements, the first of which contains the first elements // of the given arrays, the second of which contains the second elements of the given arrays, and so on. // When collections have different size, the Tuple attributes are filled with zero value. +// Play: https://go.dev/play/p/jujaA6GaJTp func Zip3[A any, B any, C any](a []A, b []B, c []C) []Tuple3[A, B, C] { size := Max([]int{len(a), len(b), len(c)}) @@ -127,6 +145,7 @@ func Zip3[A any, B any, C any](a []A, b []B, c []C) []Tuple3[A, B, C] { // Zip4 creates a slice of grouped elements, the first of which contains the first elements // of the given arrays, the second of which contains the second elements of the given arrays, and so on. // When collections have different size, the Tuple attributes are filled with zero value. +// Play: https://go.dev/play/p/jujaA6GaJTp func Zip4[A any, B any, C any, D any](a []A, b []B, c []C, d []D) []Tuple4[A, B, C, D] { size := Max([]int{len(a), len(b), len(c), len(d)}) @@ -152,6 +171,7 @@ func Zip4[A any, B any, C any, D any](a []A, b []B, c []C, d []D) []Tuple4[A, B, // Zip5 creates a slice of grouped elements, the first of which contains the first elements // of the given arrays, the second of which contains the second elements of the given arrays, and so on. // When collections have different size, the Tuple attributes are filled with zero value. +// Play: https://go.dev/play/p/jujaA6GaJTp func Zip5[A any, B any, C any, D any, E any](a []A, b []B, c []C, d []D, e []E) []Tuple5[A, B, C, D, E] { size := Max([]int{len(a), len(b), len(c), len(d), len(e)}) @@ -179,6 +199,7 @@ func Zip5[A any, B any, C any, D any, E any](a []A, b []B, c []C, d []D, e []E) // Zip6 creates a slice of grouped elements, the first of which contains the first elements // of the given arrays, the second of which contains the second elements of the given arrays, and so on. // When collections have different size, the Tuple attributes are filled with zero value. +// Play: https://go.dev/play/p/jujaA6GaJTp func Zip6[A any, B any, C any, D any, E any, F any](a []A, b []B, c []C, d []D, e []E, f []F) []Tuple6[A, B, C, D, E, F] { size := Max([]int{len(a), len(b), len(c), len(d), len(e), len(f)}) @@ -208,6 +229,7 @@ func Zip6[A any, B any, C any, D any, E any, F any](a []A, b []B, c []C, d []D, // Zip7 creates a slice of grouped elements, the first of which contains the first elements // of the given arrays, the second of which contains the second elements of the given arrays, and so on. // When collections have different size, the Tuple attributes are filled with zero value. +// Play: https://go.dev/play/p/jujaA6GaJTp func Zip7[A any, B any, C any, D any, E any, F any, G any](a []A, b []B, c []C, d []D, e []E, f []F, g []G) []Tuple7[A, B, C, D, E, F, G] { size := Max([]int{len(a), len(b), len(c), len(d), len(e), len(f), len(g)}) @@ -239,6 +261,7 @@ func Zip7[A any, B any, C any, D any, E any, F any, G any](a []A, b []B, c []C, // Zip8 creates a slice of grouped elements, the first of which contains the first elements // of the given arrays, the second of which contains the second elements of the given arrays, and so on. // When collections have different size, the Tuple attributes are filled with zero value. +// Play: https://go.dev/play/p/jujaA6GaJTp func Zip8[A any, B any, C any, D any, E any, F any, G any, H any](a []A, b []B, c []C, d []D, e []E, f []F, g []G, h []H) []Tuple8[A, B, C, D, E, F, G, H] { size := Max([]int{len(a), len(b), len(c), len(d), len(e), len(f), len(g), len(h)}) @@ -272,6 +295,7 @@ func Zip8[A any, B any, C any, D any, E any, F any, G any, H any](a []A, b []B, // Zip9 creates a slice of grouped elements, the first of which contains the first elements // of the given arrays, the second of which contains the second elements of the given arrays, and so on. // When collections have different size, the Tuple attributes are filled with zero value. +// Play: https://go.dev/play/p/jujaA6GaJTp func Zip9[A any, B any, C any, D any, E any, F any, G any, H any, I any](a []A, b []B, c []C, d []D, e []E, f []F, g []G, h []H, i []I) []Tuple9[A, B, C, D, E, F, G, H, I] { size := Max([]int{len(a), len(b), len(c), len(d), len(e), len(f), len(g), len(h), len(i)}) @@ -306,6 +330,7 @@ func Zip9[A any, B any, C any, D any, E any, F any, G any, H any, I any](a []A, // Unzip2 accepts an array of grouped elements and creates an array regrouping the elements // to their pre-zip configuration. +// Play: https://go.dev/play/p/ciHugugvaAW func Unzip2[A any, B any](tuples []Tuple2[A, B]) ([]A, []B) { size := len(tuples) r1 := make([]A, 0, size) @@ -321,6 +346,7 @@ func Unzip2[A any, B any](tuples []Tuple2[A, B]) ([]A, []B) { // Unzip3 accepts an array of grouped elements and creates an array regrouping the elements // to their pre-zip configuration. +// Play: https://go.dev/play/p/ciHugugvaAW func Unzip3[A any, B any, C any](tuples []Tuple3[A, B, C]) ([]A, []B, []C) { size := len(tuples) r1 := make([]A, 0, size) @@ -338,6 +364,7 @@ func Unzip3[A any, B any, C any](tuples []Tuple3[A, B, C]) ([]A, []B, []C) { // Unzip4 accepts an array of grouped elements and creates an array regrouping the elements // to their pre-zip configuration. +// Play: https://go.dev/play/p/ciHugugvaAW func Unzip4[A any, B any, C any, D any](tuples []Tuple4[A, B, C, D]) ([]A, []B, []C, []D) { size := len(tuples) r1 := make([]A, 0, size) @@ -357,6 +384,7 @@ func Unzip4[A any, B any, C any, D any](tuples []Tuple4[A, B, C, D]) ([]A, []B, // Unzip5 accepts an array of grouped elements and creates an array regrouping the elements // to their pre-zip configuration. +// Play: https://go.dev/play/p/ciHugugvaAW func Unzip5[A any, B any, C any, D any, E any](tuples []Tuple5[A, B, C, D, E]) ([]A, []B, []C, []D, []E) { size := len(tuples) r1 := make([]A, 0, size) @@ -378,6 +406,7 @@ func Unzip5[A any, B any, C any, D any, E any](tuples []Tuple5[A, B, C, D, E]) ( // Unzip6 accepts an array of grouped elements and creates an array regrouping the elements // to their pre-zip configuration. +// Play: https://go.dev/play/p/ciHugugvaAW func Unzip6[A any, B any, C any, D any, E any, F any](tuples []Tuple6[A, B, C, D, E, F]) ([]A, []B, []C, []D, []E, []F) { size := len(tuples) r1 := make([]A, 0, size) @@ -401,6 +430,7 @@ func Unzip6[A any, B any, C any, D any, E any, F any](tuples []Tuple6[A, B, C, D // Unzip7 accepts an array of grouped elements and creates an array regrouping the elements // to their pre-zip configuration. +// Play: https://go.dev/play/p/ciHugugvaAW func Unzip7[A any, B any, C any, D any, E any, F any, G any](tuples []Tuple7[A, B, C, D, E, F, G]) ([]A, []B, []C, []D, []E, []F, []G) { size := len(tuples) r1 := make([]A, 0, size) @@ -426,6 +456,7 @@ func Unzip7[A any, B any, C any, D any, E any, F any, G any](tuples []Tuple7[A, // Unzip8 accepts an array of grouped elements and creates an array regrouping the elements // to their pre-zip configuration. +// Play: https://go.dev/play/p/ciHugugvaAW func Unzip8[A any, B any, C any, D any, E any, F any, G any, H any](tuples []Tuple8[A, B, C, D, E, F, G, H]) ([]A, []B, []C, []D, []E, []F, []G, []H) { size := len(tuples) r1 := make([]A, 0, size) @@ -453,6 +484,7 @@ func Unzip8[A any, B any, C any, D any, E any, F any, G any, H any](tuples []Tup // Unzip9 accepts an array of grouped elements and creates an array regrouping the elements // to their pre-zip configuration. +// Play: https://go.dev/play/p/ciHugugvaAW func Unzip9[A any, B any, C any, D any, E any, F any, G any, H any, I any](tuples []Tuple9[A, B, C, D, E, F, G, H, I]) ([]A, []B, []C, []D, []E, []F, []G, []H, []I) { size := len(tuples) r1 := make([]A, 0, size) diff --git a/tuples_example_test.go b/tuples_example_test.go new file mode 100644 index 00000000..b8eb2e99 --- /dev/null +++ b/tuples_example_test.go @@ -0,0 +1,197 @@ +package lo + +import ( + "fmt" +) + +func ExampleT2() { + result := T2("hello", 2) + fmt.Printf("%v %v", result.A, result.B) + // Output: hello 2 +} + +func ExampleT3() { + result := T3("hello", 2, true) + fmt.Printf("%v %v %v", result.A, result.B, result.C) + // Output: hello 2 true +} + +func ExampleT4() { + result := T4("hello", 2, true, foo{bar: "bar"}) + fmt.Printf("%v %v %v %v", result.A, result.B, result.C, result.D) + // Output: hello 2 true {bar} +} + +func ExampleT5() { + result := T5("hello", 2, true, foo{bar: "bar"}, 4.2) + fmt.Printf("%v %v %v %v %v", result.A, result.B, result.C, result.D, result.E) + // Output: hello 2 true {bar} 4.2 +} + +func ExampleT6() { + result := T6("hello", 2, true, foo{bar: "bar"}, 4.2, "plop") + fmt.Printf("%v %v %v %v %v %v", result.A, result.B, result.C, result.D, result.E, result.F) + // Output: hello 2 true {bar} 4.2 plop +} + +func ExampleT7() { + result := T7("hello", 2, true, foo{bar: "bar"}, 4.2, "plop", false) + fmt.Printf("%v %v %v %v %v %v %v", result.A, result.B, result.C, result.D, result.E, result.F, result.G) + // Output: hello 2 true {bar} 4.2 plop false +} + +func ExampleT8() { + result := T8("hello", 2, true, foo{bar: "bar"}, 4.2, "plop", false, 42) + fmt.Printf("%v %v %v %v %v %v %v %v", result.A, result.B, result.C, result.D, result.E, result.F, result.G, result.H) + // Output: hello 2 true {bar} 4.2 plop false 42 +} + +func ExampleT9() { + result := T9("hello", 2, true, foo{bar: "bar"}, 4.2, "plop", false, 42, "hello world") + fmt.Printf("%v %v %v %v %v %v %v %v %v", result.A, result.B, result.C, result.D, result.E, result.F, result.G, result.H, result.I) + // Output: hello 2 true {bar} 4.2 plop false 42 hello world +} + +func ExampleUnpack2() { + a, b := Unpack2(T2("hello", 2)) + fmt.Printf("%v %v", a, b) + // Output: hello 2 +} + +func ExampleUnpack3() { + a, b, c := Unpack3(T3("hello", 2, true)) + fmt.Printf("%v %v %v", a, b, c) + // Output: hello 2 true +} + +func ExampleUnpack4() { + a, b, c, d := Unpack4(T4("hello", 2, true, foo{bar: "bar"})) + fmt.Printf("%v %v %v %v", a, b, c, d) + // Output: hello 2 true {bar} +} + +func ExampleUnpack5() { + a, b, c, d, e := Unpack5(T5("hello", 2, true, foo{bar: "bar"}, 4.2)) + fmt.Printf("%v %v %v %v %v", a, b, c, d, e) + // Output: hello 2 true {bar} 4.2 +} + +func ExampleUnpack6() { + a, b, c, d, e, f := Unpack6(T6("hello", 2, true, foo{bar: "bar"}, 4.2, "plop")) + fmt.Printf("%v %v %v %v %v %v", a, b, c, d, e, f) + // Output: hello 2 true {bar} 4.2 plop +} + +func ExampleUnpack7() { + a, b, c, d, e, f, g := Unpack7(T7("hello", 2, true, foo{bar: "bar"}, 4.2, "plop", false)) + fmt.Printf("%v %v %v %v %v %v %v", a, b, c, d, e, f, g) + // Output: hello 2 true {bar} 4.2 plop false +} + +func ExampleUnpack8() { + a, b, c, d, e, f, g, h := Unpack8(T8("hello", 2, true, foo{bar: "bar"}, 4.2, "plop", false, 42)) + fmt.Printf("%v %v %v %v %v %v %v %v", a, b, c, d, e, f, g, h) + // Output: hello 2 true {bar} 4.2 plop false 42 +} + +func ExampleUnpack9() { + a, b, c, d, e, f, g, h, i := Unpack9(T9("hello", 2, true, foo{bar: "bar"}, 4.2, "plop", false, 42, "hello world")) + fmt.Printf("%v %v %v %v %v %v %v %v %v", a, b, c, d, e, f, g, h, i) + // Output: hello 2 true {bar} 4.2 plop false 42 hello world +} + +func ExampleZip2() { + result := Zip2([]string{"hello"}, []int{2}) + fmt.Printf("%v", result) + // Output: [{hello 2}] +} + +func ExampleZip3() { + result := Zip3([]string{"hello"}, []int{2}, []bool{true}) + fmt.Printf("%v", result) + // Output: [{hello 2 true}] +} + +func ExampleZip4() { + result := Zip4([]string{"hello"}, []int{2}, []bool{true}, []foo{{bar: "bar"}}) + fmt.Printf("%v", result) + // Output: [{hello 2 true {bar}}] +} + +func ExampleZip5() { + result := Zip5([]string{"hello"}, []int{2}, []bool{true}, []foo{{bar: "bar"}}, []float64{4.2}) + fmt.Printf("%v", result) + // Output: [{hello 2 true {bar} 4.2}] +} + +func ExampleZip6() { + result := Zip6([]string{"hello"}, []int{2}, []bool{true}, []foo{{bar: "bar"}}, []float64{4.2}, []string{"plop"}) + fmt.Printf("%v", result) + // Output: [{hello 2 true {bar} 4.2 plop}] +} + +func ExampleZip7() { + result := Zip7([]string{"hello"}, []int{2}, []bool{true}, []foo{{bar: "bar"}}, []float64{4.2}, []string{"plop"}, []bool{false}) + fmt.Printf("%v", result) + // Output: [{hello 2 true {bar} 4.2 plop false}] +} + +func ExampleZip8() { + result := Zip8([]string{"hello"}, []int{2}, []bool{true}, []foo{{bar: "bar"}}, []float64{4.2}, []string{"plop"}, []bool{false}, []int{42}) + fmt.Printf("%v", result) + // Output: [{hello 2 true {bar} 4.2 plop false 42}] +} + +func ExampleZip9() { + result := Zip9([]string{"hello"}, []int{2}, []bool{true}, []foo{{bar: "bar"}}, []float64{4.2}, []string{"plop"}, []bool{false}, []int{42}, []string{"hello world"}) + fmt.Printf("%v", result) + // Output: [{hello 2 true {bar} 4.2 plop false 42 hello world}] +} + +func ExampleUnzip2() { + a, b := Unzip2([]Tuple2[string, int]{T2("hello", 2)}) + fmt.Printf("%v %v", a, b) + // Output: [hello] [2] +} + +func ExampleUnzip3() { + a, b, c := Unzip3([]Tuple3[string, int, bool]{T3("hello", 2, true)}) + fmt.Printf("%v %v %v", a, b, c) + // Output: [hello] [2] [true] +} + +func ExampleUnzip4() { + a, b, c, d := Unzip4([]Tuple4[string, int, bool, foo]{T4("hello", 2, true, foo{bar: "bar"})}) + fmt.Printf("%v %v %v %v", a, b, c, d) + // Output: [hello] [2] [true] [{bar}] +} + +func ExampleUnzip5() { + a, b, c, d, e := Unzip5([]Tuple5[string, int, bool, foo, float64]{T5("hello", 2, true, foo{bar: "bar"}, 4.2)}) + fmt.Printf("%v %v %v %v %v", a, b, c, d, e) + // Output: [hello] [2] [true] [{bar}] [4.2] +} + +func ExampleUnzip6() { + a, b, c, d, e, f := Unzip6([]Tuple6[string, int, bool, foo, float64, string]{T6("hello", 2, true, foo{bar: "bar"}, 4.2, "plop")}) + fmt.Printf("%v %v %v %v %v %v", a, b, c, d, e, f) + // Output: [hello] [2] [true] [{bar}] [4.2] [plop] +} + +func ExampleUnzip7() { + a, b, c, d, e, f, g := Unzip7([]Tuple7[string, int, bool, foo, float64, string, bool]{T7("hello", 2, true, foo{bar: "bar"}, 4.2, "plop", false)}) + fmt.Printf("%v %v %v %v %v %v %v", a, b, c, d, e, f, g) + // Output: [hello] [2] [true] [{bar}] [4.2] [plop] [false] +} + +func ExampleUnzip8() { + a, b, c, d, e, f, g, h := Unzip8([]Tuple8[string, int, bool, foo, float64, string, bool, int]{T8("hello", 2, true, foo{bar: "bar"}, 4.2, "plop", false, 42)}) + fmt.Printf("%v %v %v %v %v %v %v %v", a, b, c, d, e, f, g, h) + // Output: [hello] [2] [true] [{bar}] [4.2] [plop] [false] [42] +} + +func ExampleUnzip9() { + a, b, c, d, e, f, g, h, i := Unzip9([]Tuple9[string, int, bool, foo, float64, string, bool, int, string]{T9("hello", 2, true, foo{bar: "bar"}, 4.2, "plop", false, 42, "hello world")}) + fmt.Printf("%v %v %v %v %v %v %v %v %v", a, b, c, d, e, f, g, h, i) + // Output: [hello] [2] [true] [{bar}] [4.2] [plop] [false] [42] [hello world] +}