Documentation
¶
Overview ¶
Package res provides a generic, Rust-inspired `Result[T]` type for expressive error handling.
Core Concept ¶
A `Result[T]` is a type that represents either a success (containing a value of type T) or a failure (containing an error). It is a monadic type that allows for chaining operations in a clean, readable way, especially in data processing pipelines where each step can fail.
This pattern provides an alternative to returning `(value, error)` pairs at each step. Instead of checking for an error after every call, you can chain methods and handle the final result once.
Warning: Paradigm and Trade-offs ¶
While powerful, the `Result` type introduces a paradigm that is not idiomatic Go. Standard Go error handling (returning `(T, error)`) is simpler and more direct for most use cases. The `Result` type is best suited for specific scenarios like complex data transformation chains where the flow of data is the primary concern.
Be especially cautious with methods like `Unwrap` and `Expect`, which panic on an `Err` value. They should only be used when an error is considered a fatal, unrecoverable bug, similar to the `must` package.
Usage: Data Processing Pipeline ¶
The primary benefit of `Result` is in chaining operations where any step can fail. The chain short-circuits as soon as an error occurs.
Consider a sequence of operations: 1. Get a filename from a map. 2. Read the file content. 3. Parse the content into a number.
// Define helper functions that each return a Result.
func getFilename(config map[string]string) res.Result[string] {
if name, ok := config["filename"]; ok {
return res.Ok(name)
}
return res.Err[string](errors.New("filename not found in config"))
}
func readContent(filename string) res.Result[string] {
// Simulate reading a file.
if filename == "data.txt" {
return res.Ok("12345")
}
return res.Err[string](fmt.Errorf("file not found: %s", filename))
}
func parseNumber(content string) res.Result[int] {
n, err := strconv.Atoi(content)
return res.Of(n, err)
}
// Now, chain these operations together.
config := map[string]string{"filename": "data.txt"}
// The `AndThen` method chains functions that return a Result.
// The chain stops at the first `Err`.
finalResult := getFilename(config).
AndThen(readContent).
AndThen(parseNumber)
// Safely handle the outcome.
if finalResult.IsErr() {
fmt.Printf("Pipeline failed: %v\n", finalResult.Err())
} else {
// No error occurred, we can safely get the value.
fmt.Printf("Pipeline succeeded, result: %d\n", finalResult.Unwrap())
}
Index ¶
- func Or[T any](v T, err error, defaultValue T) T
- func OrZero[T any](v T, err error) T
- type Pair
- func (p Pair[A, B]) First() A
- func (p Pair[A, B]) Map(fnA func(A) A, fnB func(B) B) Pair[A, B]
- func (p Pair[A, B]) MapFirst(fn func(A) A) Pair[A, B]
- func (p Pair[A, B]) MapSecond(fn func(B) B) Pair[A, B]
- func (p Pair[A, B]) Second() B
- func (p Pair[A, B]) Swap() Pair[B, A]
- func (p Pair[A, B]) Values() (A, B)
- func (p Pair[A, B]) WithFirst(first A) Pair[A, B]
- func (p Pair[A, B]) WithSecond(second B) Pair[A, B]
- type Result
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type Pair ¶ added in v0.12.0
type Pair[A, B any] struct { // contains filtered or unexported fields }
Pair represents an immutable pair of two different types A and B. It's useful for combining two values of different types into a single value that can be passed around and manipulated as a unit.
func (Pair[A, B]) First ¶ added in v0.12.0
func (p Pair[A, B]) First() A
First returns the first value of the pair.
func (Pair[A, B]) Map ¶ added in v0.12.0
Map applies the given functions to the pair's values and returns a new pair. This allows transforming both values in the pair in a single operation.
func (Pair[A, B]) MapFirst ¶ added in v0.12.0
MapFirst applies the given function to the first value of the pair. The second value remains unchanged.
func (Pair[A, B]) MapSecond ¶ added in v0.12.0
MapSecond applies the given function to the second value of the pair. The first value remains unchanged.
func (Pair[A, B]) Second ¶ added in v0.12.0
func (p Pair[A, B]) Second() B
Second returns the second value of the pair.
func (Pair[A, B]) Values ¶ added in v0.12.0
func (p Pair[A, B]) Values() (A, B)
Values returns both values from the pair.
func (Pair[A, B]) WithFirst ¶ added in v0.12.0
WithFirst returns a new Pair with the first value replaced by the given value.
func (Pair[A, B]) WithSecond ¶ added in v0.12.0
WithSecond returns a new Pair with the second value replaced by the given value.
type Result ¶
type Result[T any] struct { // contains filtered or unexported fields }
Result is a type that represents either a success (containing a value of type T) or a failure (containing an error). It is a monadic type that allows for chaining operations in a clean, readable way. See the package documentation for more details and usage examples.
func Of ¶
Of converts a standard Go (value, error) pair into a Result. If err is not nil, it returns an Err result; otherwise, it returns an Ok result.
func (Result[T]) Expect ¶
Expect returns the contained Ok value. It panics with a custom message if the result is an Err. This is similar to Unwrap but provides a more context-specific panic message.
func (Result[T]) Ok ¶
Ok returns the contained value and a boolean indicating if the result was Ok. This provides a safe, idiomatic Go way to access the value.
func (Result[T]) Unpack ¶ added in v0.11.0
Unpack unpacks the Result into the original value and error pair.
Return: - T: Included value (if Result is Ok) - error: Contains an error (if Result is Err)
This method provides a way to convert the Result type back to a standard Go (value, error) pair, Facilitate interaction with existing code or APIs that expect this form of return.
func (Result[T]) Unwrap ¶
func (r Result[T]) Unwrap() T
Unwrap returns the contained Ok value. It panics if the result is an Err. Because this function may panic, it should only be used when the caller is certain that the result is Ok, or when a panic is the desired behavior. See also: Expect, UnwrapOr.