A go package for wrapping builtin types to represent the lack of value without pointers.
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
template
.godocdown.md
.travis.yml
LICENSE
Makefile
README.md
benchmark_test.go
bool_generated.go
byte_generated.go
complex128_generated.go
complex64_generated.go
doc.go
example_test.go
float32_generated.go
float64_generated.go
int16_generated.go
int32_generated.go
int64_generated.go
int8_generated.go
int_generated.go
rune_generated.go
string_generated.go
time_generated.go
types.go
uint16_generated.go
uint32_generated.go
uint64_generated.go
uint8_generated.go
uint_generated.go
uintptr_generated.go

README.md

optional

Go Report Card Codecov Build Status Go docs

go get 4d63.com/optional
import 4d63.com/optional

Package optional exports types that wrap the builtin types (int, bool, etc) to represent the lack of value. The types guarantee safety by requiring the developer to unwrap them to get to the inner value. This prevents a nil value being operated on. Optionals marshal to XML and JSON like their underlying type, and omitempty works just like their wrapped type would with a pointer, but without the use of pointers.

These types are an alternative to using pointers, zero values, or similar null wrapper packages. Unlike similar solutions these will omit correctly from XML and JSON without the use of pointers and the compiler will ensure their value is not used when empty.

The package also contains a template that you can use with go generate to create optional types for your own types. See below for instructions on how to use the template.

Examples

Wrap a pointer in an optional:

var i *int = ...
o := optional.OfIntPtr(i)

Unwrap it safely:

o.If(func(i int) {
	// called if o is not empty
})

if _, ok := o.Get(); ok {
	// ok is true if o is not empty
}

Or get it's value with a fallback to a default:

_ := o.ElseZero() // returns the zero value if empty

_ := o.Else(100) // returns 100 if o is empty

_ := o.ElseFunc(func() {
	// called if o is empty
	return 100
})

XML and JSON are supported out of the box. Use omitempty to omit the field when the optional is empty:

s := struct {
	Int1 optional.Int `json:"int1,omitempty"`
	Int2 optional.Int `json:"int2,omitempty"`
	Int3 optional.Int `json:"int3,omitempty"`
}{
	Int1: optional.EmptyInt(),
	Int2: optional.OfInt(1000),
	Int3: optional.OfIntPtr(nil),
}

output, _ := json.Marshal(s)

// output = {"int2":1000}

Templates

Use the Optional template for your own types by installing gotemplate.

go get github.com/ncw/gotemplate

Then add a go generate comment for your type to any .go file in your package.

//go:generate gotemplate "4d63.com/optional/template" OptionalMyType(MyType)

Examples

See the examples for more approaches to use.

Documentation

See the godoc.