goptional

package module
v0.1.1 Latest Latest
Warning

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

Go to latest
Published: Nov 6, 2025 License: MIT Imports: 1 Imported by: 0

README

Goptional

Provides a generic Optional[T] type for handling nullable or absent values in a type-safe manner. It is designed for general-purpose use and works with any type T

CI Status Go Report Card Release Version License Go package documentation

Features

  • Zero Dependencies: No external dependencies, making it lightweight and easy to integrate.
  • Type Safety: Generic implementation for any type T.
  • JSON Compatibility: Implements json.Marshaler and json.Unmarshaler for integration with JSON serialization and deserialization.
  • Pointer Avoidance: Uses a struct-based approach to handle optionality without pointers.
  • Zero Value Distinction: Clearly distinguishes between zero values (like 0, "", false) and absent values.
  • General Purpose: Can be used in any context where you need to represent optional values (it does not need to be JSON-specific).

When to Use Optional vs Pointers

Use Optional[T] instead of *T when:

  • You want to avoid nil pointer dereference issues
  • You need to distinguish between zero values and absent values
  • You want explicit type safety for optional fields

Usage

Installation

go get github.com/eduardolat/goptional

Basic Usage

import "github.com/eduardolat/goptional"

// Create optional values (the direct way)
optionalValue := goptional.Optional[string]{
  Value:  "hello",
  Present: true,
}

// Create optional values using helpers
presentValue := goptional.Some("hello")
absentValue := goptional.None[string]()

// Check presence
if presentValue.Present {
  fmt.Println("Value:", presentValue.Value) // Direct access to Value field
}

// Get value or default
defaultValue := absentValue.Or("default")
fmt.Println(defaultValue) // "default"

JSON Serialization

Any absent value is always serialized as null in JSON. This makes it predictable and consistent for API responses.

type User struct {
  Name  goptional.Optional[string] `json:"name"`
  Age   goptional.Optional[int]    `json:"age"`
  Email goptional.Optional[string] `json:"email"`
}

// Unmarshaling JSON with null values
data := `{"name": "John", "age": null, "email": "john@example.com"}`
var user User
json.Unmarshal([]byte(data), &user)

fmt.Println(user.Name.Present)  // true
fmt.Println(user.Name.Value)    // "John"
fmt.Println(user.Age.Present)   // false
fmt.Println(user.Email.Present) // true
fmt.Println(user.Email.Value)   // "john@example.com"

// Marshaling back to JSON - absent values become null
jsonData, _ := json.Marshal(user)
// {"name":"John","age":null,"email":"john@example.com"}

Working with Different Types

// Numbers
age := goptional.Some(25)
height := goptional.None[float64]()

// Booleans
isActive := goptional.Some(true)
isVerified := goptional.None[bool]()

// Slices
tags := goptional.Some([]string{"go", "optional"})
emptyTags := goptional.None[[]string]()

// Custom types
type Address struct {
    Street string
    City   string
}

homeAddress := goptional.Some(Address{Street: "123 Main St", City: "Anytown"})
workAddress := goptional.None[Address]()

Method Reference

Constructors
  • Some[T](value T) Optional[T] - Creates an optional with a present value
  • None[T]() Optional[T] - Creates an optional with no value (absent)
Value Access
  • .Or(defaultValue T) T - Returns the value if present, otherwise returns the default
Direct Field Access
  • .Present bool - Boolean flag indicating if value is present
  • .Value T - The actual value (zero value of T when Present is false)

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Optional

type Optional[T any] struct {
	Present bool // True if the value is present; false otherwise.
	Value   T    // The actual value when present; otherwise, the zero value of T.
}

Optional represents a general purpose value that may or may not be present.

Can be used for handling nullable JSON fields.

It is generic and works with any type T.

func None

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

None creates an Optional[T] with no present value, using the zero value of T.

func Some

func Some[T any](v T) Optional[T]

Some creates an Optional[T] with a present value set to v.

func (Optional[T]) MarshalJSON

func (n Optional[T]) MarshalJSON() ([]byte, error)

MarshalJSON implements json.Marshaler.

If the value is absent, it returns "null".

If present, it marshals the value.

func (Optional[T]) Or

func (o Optional[T]) Or(defaultVal T) T

Or returns the value if present; otherwise, returns the provided default value.

Example:

opt1 := optional.Some(42)
val1 := opt.Or(100) // val1 is 42

opt2 := optional.None[int]()
val2 := opt2.Or(100) // val2 is 100

func (*Optional[T]) UnmarshalJSON

func (n *Optional[T]) UnmarshalJSON(data []byte) error

UnmarshalJSON implements json.Unmarshaler.

It sets the Optional to absent if the JSON is "null"; otherwise, it unmarshals the value and marks it as present.

Directories

Path Synopsis
internal

Jump to

Keyboard shortcuts

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