option

package
v0.2.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 28, 2024 License: GPL-3.0, LGPL-3.0 Imports: 5 Imported by: 0

README

A simple implementation of `Option[T]` that mimicks [`Option` from Rust](https://doc.rust-lang.org/std/option/).

Option[T]

The type Option[T] mimicks Option<T> Rust idiom. It is a union type that is either a value of the type T or None.

The main use of Option[T] is to provide flag if the operation failed, without details.

func AddKeyValues(m map[string]int, key1, key2 string) (int, bool) {
	v1, ok1 := m[key1]
	v2, ok2 := m[key2]
	if ok1 && ok2 {
		return (v1 + v2), true
	} else {
		return 0, false
	}
}

Here is how this function could be implemented using Option style.

import "github.com/pakuula/go-rusty/option"

func AddKeyValuesOpt(m map[string]int, key1, key2 string) (res option.Option[int]) {
	defer option.Catch(&res)
	v1 := option.MapGet(m, key1).Must()
	v2 := option.MapGet(m, key2).Must()
	return option.Some(v1 + v2)
}

The function option.MapGet return an Option[T] object that is either the value from the map or None. Must() panics with an error if the object is None, while defer option.Catch(&res) catches missing values and writes None to the returned option res.

The constructor Option.Some[T](value T) builds a Option[T] with the given value.

1. Throw/Catch

The Rust operator ? (the question mark) is used to simplify code that uses Option types. Ending the expression with ? will result in the unwrapped value, unless the Option is None, in which case None is returned early from the enclosing function.

fn add_last_numbers(stack: &mut Vec<i32>) -> Option<i32> {
    Some(stack.pop()? + stack.pop()?)
}

In this example execution is terminated as soon as any of ?-enclosed calls returns an error. It is similar to throwing and exception though ? operator Options in Option.Err rather than exception propagation through the stack.

The method Option.Must and the function Catch implement the alternative to the question mark oprator.

func AddKeyValuesOpt(m map[string]int, key1, key2 string) (res option.Option[int]) {
	defer option.Catch(&res)
	v1 := option.MapGet(m, key1).Must()
	v2 := option.MapGet(m, key2).Must()
	return option.Some(v1 + v2)
}

The method Option.Must panics with an object of the internal type Option.checkError. The function option.Catch[T](*Option[T]) recovers the panics and writes None to the Option to be returned.

func ReturnOption() (res Option[SomeType]) {
    defer option.Catch(&res);

    x := SomeOtherOption().Must()

    return ProcessX(x)
}

Important notes:

  • the return value must be named, e.g. (res Option[SomeType]),
  • the Catch must be called in the defer statement: defer option.Catch(&res),
  • if the reason of the panics is not Must then the error is not intercepted and panic propagets through the stack.

2. Constructors

2.1. WrapOk (value,bool) pair

De-facto standard idiom of Go is to return a pair (T, bool) where the boolean value is true if the operation was successfull.

The function Option.WrapOk converts such a pair into an object Option[T].

    fileInfoOption := Option.WrapOk(cache.GetFileInfo("filename.txt))

Properties:

  • if ok is true:
    • Option.WrapOk(val, true).IsNone() is false,
    • Option.WrapOk(val, true).Unwrap() never panics,
    • Option.WrapOk(val, true).Unwrap() returns val,
  • if ok is false:
    • Option.WrapOk(val, false).IsNone() is true,
    • Option.WrapOk(val, false).Unwrap() panics,
2.2. Store a valueue

The function Option.Some[T](val T) Option[T] construct a non-none object.

  • Option.Some(val).IsNone() is false,
  • Option.Some(val).Unwrap() never panics,
  • Option.Some(val).Unwrap() returns val.
2.3. Store None

The function func Err[T](err error) Option[T] creates an error object.

  • Option.Err(err).IsNone() is false,
  • Option.Err(err).Unwrap() panics,
  • Option.Err(err).Err() returns None.

3. Access to stored data

These methods extract the contained value in a Option[T] when it is not the None variant. If the Option is None:

  • Option.Unwrap() panics with a generic message
  • Option.Expect(msg string) panics with a provided custom message
  • Option.Expectf(format string, a ...any) panics with a provided custom formatted message
  • Option.UnwrapOr(val T) the provided custom value
  • Option.UnwrapOrDefault() returns the default value of the type T

The method Option.UnwrapWithOk() (T,bool) converts the Option[T] object to the standard Golang pair (T, bool) where the boolean value is true for value options.

4. Transforming contained values

The following functions mimic map method of Rust Option<T,E> class.

  • func Apply[T any, U any](from Option[T], f func(T) U) Option[U] applies f to the stored value or keeps None.
  • func ApplyE[T any, U any](from Option[T], f func(T) (U, error)) Option[U] applies f to the stored value or keeps None. If f returns an error, sets the Option to None.
  • func ApplyOption[T any, U any](from Option[T], f func(T) Option[U]) Option[U] applies f to the stored value or keeps None unchanged. If f returns None, returns None.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var ErrUnwrap = errors.New("unwrapping none")

Functions

func Catch

func Catch[T any](res *Option[T])

Defer Catch(&res) to convert failed invocation of Must into Option

func MustOk

func MustOk[T any](val T, ok bool) T

Returns the value of panics with the catchable value.

Types

type Option

type Option[T any] struct {
	// contains filtered or unexported fields
}

A value or None

func Apply

func Apply[T any, U any](from Option[T], f func(T) U) Option[U]

Applies f to the stored value or keeps the error unchanged

func ApplyE

func ApplyE[T any, U any](from Option[T], f func(T) (U, error)) Option[U]

Applies f to the stored value or keeps error unchanged. If f returns None, set the error

func ApplyOption

func ApplyOption[T any, U any](from Option[T], f func(T) Option[U]) Option[U]

Applies f to the stored value or keeps error unchanged. If f returns None, set the error

func Deref

func Deref[T any](res Option[*T]) Option[T]

Derefences Option[*T] - produces Option[T]

func MapGet

func MapGet[K comparable, V any](m map[K]V, key K) Option[V]

func None

func None[T any]() Option[T]

func Ptr

func Ptr[T any](res *Option[T]) Option[*T]

Converts to Option[*T]

func Some

func Some[T any](value T) Option[T]

Constructors

func UnmarshalJson

func UnmarshalJson[T any](data []byte) Option[T]

Unmarshal JSON data into a value of the type T or error

func UnmarshalJsonString

func UnmarshalJsonString[T any](data string) Option[T]

Unmarshal JSON string into a value of the type T or error

func WrapErr

func WrapErr[T any](val T, err error) Option[T]

func WrapOk

func WrapOk[T any](val T, ok bool) Option[T]

func (Option[T]) Expect

func (self Option[T]) Expect(msg string) T

Returns the stored value or panics with the given message

func (Option[T]) Expectf

func (self Option[T]) Expectf(format string, a ...any) T

Returns the stored value or panics with the given formatted message

func (Option[T]) IsNone

func (self Option[T]) IsNone() bool

True if self is None

func (Option[T]) IsSome

func (self Option[T]) IsSome() bool

True is self contains a value

func (Option[T]) IsSomeAnd

func (self Option[T]) IsSomeAnd(cond func(T) bool) bool

True is self contains a value and it matches the condition

func (Option[T]) Must

func (self Option[T]) Must() T

Extracts the stored value or panics with a catchable value.

func (Option[T]) String

func (self Option[T]) String() string

Builds a string representation of the Option object. If it is None, returns "None" If T has String method, calls String If T has ToString method, calls ToString If T has MarshalText method, calls MarshalText Otherwise calls fmt.Sprint(self.Unwrap())

func (Option[T]) Unwrap

func (self Option[T]) Unwrap() T

Returns the stored value or panics

func (Option[T]) UnwrapOr

func (self Option[T]) UnwrapOr(valueIfNone T) T

Returns the stored value or the provided default value

func (Option[T]) UnwrapOrDefault

func (self Option[T]) UnwrapOrDefault() T

Returns the stored value or the default value for the type T

func (Option[T]) UnwrapUnsafe

func (self Option[T]) UnwrapUnsafe() T

Returns the stored value without checking IsNone()

func (Option[T]) UnwrapWithOk

func (self Option[T]) UnwrapWithOk() (T, bool)

Converts to the pair (value, bool)

Directories

Path Synopsis
examples
experiments

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL