is

package
v1.1.0 Latest Latest
Warning

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

Go to latest
Published: Dec 3, 2025 License: Apache-2.0 Imports: 2 Imported by: 0

README

is

A comprehensive value checking and comparison package for Go that provides utilities for boolean operations, zero/nil/empty checks, and value comparisons.

Features

  • Boolean Operations: Logical negation and boolean value checks
  • Zero Value Checks: Check if values are zero for their type
  • Nil Checks: Comprehensive nil checking for reference types
  • Empty Checks: Check for empty values across different types
  • Value Comparison: Equality and deep equality checks
  • Type Safety: Full compile-time type checking with generics

Installation

go get github.com/go4x/goal/is

Quick Start

package main

import (
    "fmt"
    "github.com/go4x/goal/is"
)

func main() {
    // Zero value checks
    if is.Zero(0) {
        fmt.Println("Value is zero")
    }

    // Nil checks
    var ptr *int
    if is.Nil(ptr) {
        fmt.Println("Pointer is nil")
    }

    // Empty checks
    if is.Empty("") {
        fmt.Println("String is empty")
    }

    // Value comparison
    if is.Eq(42, 42) {
        fmt.Println("Values are equal")
    }
}

Core Functions

Boolean Operations
Not - Logical Negation
import "github.com/go4x/goal/is"

// Negate a boolean value
fmt.Println(is.Not(true))   // false
fmt.Println(is.Not(false))  // true

// Use in conditions
supported := true
if is.Not(supported) {
    fmt.Println("not supported")
} else {
    fmt.Println("supported")
}
True - Check if True
import "github.com/go4x/goal/is"

// Check if value is true
fmt.Println(is.True(true))   // true
fmt.Println(is.True(false))  // false
False - Check if False
import "github.com/go4x/goal/is"

// Check if value is false
fmt.Println(is.False(true))   // false
fmt.Println(is.False(false))  // true
Zero Value Checks
Zero - Zero Value Check
import "github.com/go4x/goal/is"

// Check for zero values
fmt.Println(is.Zero(0))        // true
fmt.Println(is.Zero(""))      // true
fmt.Println(is.Zero(false))   // true
fmt.Println(is.Zero(42))      // false
fmt.Println(is.Zero("hello")) // false

// With different types
fmt.Println(is.Zero(0.0))     // true
fmt.Println(is.Zero(0.0))     // true
fmt.Println(is.Zero([]int{}))  // false (empty slice is not zero)
NotZero - Non-Zero Value Check
import "github.com/go4x/goal/is"

// Check for non-zero values
fmt.Println(is.NotZero(42))     // true
fmt.Println(is.NotZero("hello")) // true
fmt.Println(is.NotZero(0))      // false
fmt.Println(is.NotZero(""))     // false
Nil Checks
Nil - Nil Check
import "github.com/go4x/goal/is"

var ptr *int
fmt.Println(is.Nil(ptr))        // true
fmt.Println(is.Nil(nil))        // true
fmt.Println(is.Nil([]int{}))    // false (empty slice is not nil)
fmt.Println(is.Nil((*int)(nil))) // true

// With different reference types
var m map[string]int
fmt.Println(is.Nil(m))          // true

var ch chan int
fmt.Println(is.Nil(ch))         // true
NotNil - Non-Nil Check
import "github.com/go4x/goal/is"

// Check for non-nil values
ptr := &42
fmt.Println(is.NotNil(ptr))     // true
fmt.Println(is.NotNil([]int{})) // true (empty slice is not nil)
fmt.Println(is.NotNil(nil))     // false

// With maps and channels
m := make(map[string]int)
fmt.Println(is.NotNil(m))       // true

ch := make(chan int)
fmt.Println(is.NotNil(ch))      // true
Empty Checks
Empty - Empty Value Check
import "github.com/go4x/goal/is"

// Check for empty values
fmt.Println(is.Empty(""))                    // true
fmt.Println(is.Empty([]int{}))              // true
fmt.Println(is.Empty(map[string]int{}))     // true
fmt.Println(is.Empty(0))                    // true
fmt.Println(is.Empty("hello"))              // false
fmt.Println(is.Empty([]int{1, 2}))          // false

// With different types
fmt.Println(is.Empty(nil))                  // true
var ptr *int
fmt.Println(is.Empty(ptr))                  // true
NotEmpty - Non-Empty Value Check
import "github.com/go4x/goal/is"

// Check for non-empty values
fmt.Println(is.NotEmpty("hello"))           // true
fmt.Println(is.NotEmpty([]int{1, 2}))       // true
fmt.Println(is.NotEmpty(42))                // true
fmt.Println(is.NotEmpty(""))                // false
fmt.Println(is.NotEmpty([]int{}))           // false
Value Comparison
Eq - Equality Check
import "github.com/go4x/goal/is"

// Compare values
fmt.Println(is.Eq(42, 42))              // true
fmt.Println(is.Eq("hello", "hello"))    // true
fmt.Println(is.Eq(42, 43))              // false
fmt.Println(is.Eq("hello", "hi"))       // false

// With different types
fmt.Println(is.Eq(true, true))          // true
fmt.Println(is.Eq(3.14, 3.14))          // true

// Pointers - compare by value, not by address
v1, v2 := 42, 42
fmt.Println(is.Eq(&v1, &v2))            // true

// Structs
type Person struct {
    Name string
    Age  int
}
p1 := Person{Name: "John", Age: 30}
p2 := Person{Name: "John", Age: 30}
fmt.Println(is.Eq(p1, p2))              // true

// Deep comparison using reflection
slice1 := []int{1, 2, 3}
slice2 := []int{1, 2, 3}
slice3 := []int{1, 2, 4}

fmt.Println(is.Eq(slice1, slice2)) // true
fmt.Println(is.Eq(slice1, slice3)) // false

// Compare maps
map1 := map[string]int{"a": 1, "b": 2}
map2 := map[string]int{"a": 1, "b": 2}
map3 := map[string]int{"a": 1, "b": 3}

fmt.Println(is.Eq(map1, map2)) // true
fmt.Println(is.Eq(map1, map3)) // false

// Compare structs
type Person struct {
    Name string
    Age  int
}

p1 := Person{Name: "John", Age: 30}
p2 := Person{Name: "John", Age: 30}
p3 := Person{Name: "Jane", Age: 30}

fmt.Println(is.Eq(p1, p2)) // true
fmt.Println(is.Eq(p1, p3)) // false

// compare functions, only return true if both are nil, otherwise return false

type Func func() int
var v1 Func = nil
var v2 Func = nil
fmt.Println(is.Eq(v1, v2)) // true
v1 := func() int { return 1 }
v2 := v1
v3 := func() int { return 1 }
fmt.Println(is.Eq(v1, v2)) // false
fmt.Println(is.Eq(v1, v3)) // false
Neq - Inequality Check
import "github.com/go4x/goal/is"

// Check inequality
fmt.Println(is.Neq(42, 43))          // true
fmt.Println(is.Neq("hello", "hi"))   // true
fmt.Println(is.Neq(42, 42))          // false
fmt.Println(is.Neq("hello", "hello")) // false

Advanced Usage

Data Validation
import "github.com/go4x/goal/is"

// Validate user input
func ValidateUser(user User) error {
    if is.Empty(user.Name) {
        return errors.New("name is required")
    }

    if is.Zero(user.Age) || user.Age < 0 {
        return errors.New("age must be positive")
    }

    if is.Nil(user.Email) || is.Empty(*user.Email) {
        return errors.New("email is required")
    }

    return nil
}

type User struct {
    Name  string
    Age   int
    Email *string
}
Configuration Validation
import "github.com/go4x/goal/is"

// Validate configuration
func ValidateConfig(config Config) error {
    if is.Empty(config.Host) {
        return errors.New("host is required")
    }

    if is.Zero(config.Port) || config.Port <= 0 {
        return errors.New("port must be positive")
    }

    if is.Nil(config.Database) {
        return errors.New("database config is required")
    }

    return nil
}
API Response Processing
import "github.com/go4x/goal/is"

// Process API responses
func ProcessResponse(response *APIResponse) error {
    if is.Nil(response) {
        return errors.New("response is nil")
    }

    if is.Empty(response.Data) {
        return errors.New("response data is empty")
    }

    // Check if response is successful
    if is.NotEqual(response.Status, "success") {
        return fmt.Errorf("unexpected status: %s", response.Status)
    }

    return nil
}
Functional Programming
import "github.com/go4x/goal/is"

// Filter items based on checks
func FilterValidItems(items []Item) []Item {
    var valid []Item
    for _, item := range items {
        if is.NotEmpty(item.Name) && is.NotZero(item.Price) {
            valid = append(valid, item)
        }
    }
    return valid
}

// Compare collections
func AreCollectionsEqual(a, b []int) bool {
    return is.EqDeep(a, b)
}

Performance Considerations

Zero Value Checks
  • Zero/NotZero: O(1) - Direct comparison with zero value
  • Empty/NotEmpty: O(1) for most types, O(n) for slices/maps (length check)
  • Nil/NotNil: O(1) - Reflection-based nil check
Comparison Operations
  • Eq/Neq: O(1) - Direct or reflection-based equality check
  • EqDeep: O(n) - Reflection-based deep comparison
Best Practices
  1. Use Zero/NotZero for simple zero-value checks with comparable types
  2. Use Empty/NotEmpty for comprehensive empty checks across all types
  3. Use Nil/NotNil for reference type nil checks
  4. Use Eq/Neq for value comparisons (including pointers, structs, interfaces)
  5. Use EqDeep for complex nested structure comparisons

Thread Safety

⚠️ Important: All functions in this package are thread-safe and can be called concurrently from multiple goroutines. However, the underlying data being checked must be thread-safe if accessed concurrently.

API Reference

Boolean Functions
Function Description Time Complexity
Not(v) Return logical negation of boolean O(1)
True(v) Return true if value is true O(1)
False(v) Return true if value is false O(1)
Check Functions
Function Description Time Complexity
Zero(value) Check if value is zero O(1)
NotZero(value) Check if value is not zero O(1)
Nil(value) Check if value is nil O(1)
NotNil(value) Check if value is not nil O(1)
Empty(value) Check if value is empty O(1)
NotEmpty(value) Check if value is not empty O(1)
Comparison Functions
Function Description Time Complexity
Equal(a, b) Check if values are equal O(1)
NotEqual(a, b) Check if values are not equal O(1)
DeepEqual(a, b) Deep comparison using reflection O(n)

Use Cases

1. Input Validation
import "github.com/go4x/goal/is"

// Validate input data
func ValidateInput(data InputData) error {
    if is.Empty(data.Name) {
        return errors.New("name is required")
    }

    if is.Zero(data.Age) || data.Age < 0 {
        return errors.New("age must be positive")
    }

    if is.Nil(data.Email) || is.Empty(*data.Email) {
        return errors.New("email is required")
    }

    return nil
}
2. Configuration Checking
import "github.com/go4x/goal/is"

// Check configuration values
func CheckConfig(config Config) error {
    if is.Empty(config.Host) {
        return errors.New("host cannot be empty")
    }

    if is.Zero(config.Port) {
        return errors.New("port must be specified")
    }

    return nil
}
3. Data Comparison
import "github.com/go4x/goal/is"

// Compare data structures
func CompareData(old, new Data) bool {
    return is.EqDeep(old, new)
}

// Check if values changed
func HasChanged(old, new string) bool {
    return is.Neq(old, new)
}
4. Conditional Logic
import "github.com/go4x/goal/is"

// Use in conditional logic
func ProcessData(data string) error {
    if is.Empty(data) {
        return errors.New("data is empty")
    }

    if is.NotEmpty(data) {
        // Process non-empty data
        return process(data)
    }

    return nil
}

License

This package is part of the goal project and follows the same license terms.

Documentation

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func Empty

func Empty(v any) bool

Empty checks if the value is empty (zero value or empty string/slice/map). This function provides a comprehensive check for "empty" values across different types.

Parameters:

  • v: The value to check (can be any type)

Returns:

  • bool: true if the value is considered empty

Empty conditions:

  • nil values
  • empty strings ("")
  • empty slices, maps, arrays (length 0)
  • nil pointers and interfaces
  • zero values for other types

Example:

is.Empty("")           // true
is.Empty([]int{})      // true
is.Empty(map[string]int{}) // true
is.Empty(0)            // true
is.Empty("hello")      // false
is.Empty([]int{1, 2})  // false
Example

ExampleIsEmpty demonstrates the IsEmpty function

package main

import (
	"fmt"

	"github.com/go4x/goal/is"
)

func main() {
	fmt.Println(is.Empty(""))               // true
	fmt.Println(is.Empty([]int{}))          // true
	fmt.Println(is.Empty(map[string]int{})) // true
	fmt.Println(is.Empty(0))                // true
	fmt.Println(is.Empty("hello"))          // false
	fmt.Println(is.Empty([]int{1, 2}))      // false
}
Output:

true
true
true
true
false
false

func Eq

func Eq(a, b any) bool

Eq checks if two values are equal. For basic types, it uses the == operator. For pointers, it compares the values they point to (not the pointer addresses). For structs and other composite types, it performs a deep comparison.

Parameters:

  • a: The first value to compare
  • b: The second value to compare

Returns:

  • bool: true if the values are equal, false otherwise

Example:

// Basic types
is.Eq(42, 42)        // true
is.Eq("hello", "hi") // false

// Pointers - compares values, not addresses
val1, val2 := 42, 42
ptr1, ptr2 := &val1, &val2
is.Eq(ptr1, ptr2)    // true (values are equal, even though pointers differ)

// Structs
type Person struct {
    Name string
    Age  int
}
p1 := Person{Name: "John", Age: 30}
p2 := Person{Name: "John", Age: 30}
is.Eq(p1, p2)        // true

For functions, it uses reflect.DeepEqual, only return true if both are nil, otherwise return false Example:

type Func func() int
var v1 Func = nil
var v2 Func = nil
is.Eq(v1, v2) // true
v1 := func() int { return 1 }
v2 := v1
v3 := func() int { return 1 }
is.Eq(v1, v2) // false
is.Eq(v1, v3) // false
Example

ExampleEq demonstrates the Eq function

package main

import (
	"fmt"

	"github.com/go4x/goal/is"
)

func main() {
	fmt.Println(is.Eq(42, 42))        // true
	fmt.Println(is.Eq("hello", "hi")) // false
	fmt.Println(is.Eq(0, 0))          // true

	slice1 := []int{1, 2, 3}
	slice2 := []int{1, 2, 3}
	slice3 := []int{1, 2, 4}
	fmt.Println(is.Eq(slice1, slice2)) // true
	fmt.Println(is.Eq(slice1, slice3)) // false

	map1 := map[string]int{"a": 1, "b": 2}
	map2 := map[string]int{"a": 1, "b": 2}
	map3 := map[string]int{"a": 1, "b": 3}
	fmt.Println(is.Eq(map1, map2)) // true
	fmt.Println(is.Eq(map1, map3)) // false

	// Compare structs
	type Person struct {
		Name string
		Age  int
	}

	p1 := Person{Name: "John", Age: 30}
	p2 := Person{Name: "John", Age: 30}
	p3 := Person{Name: "Jane", Age: 30}
	fmt.Println(is.Eq(p1, p2)) // true
	fmt.Println(is.Eq(p1, p3)) // false

	type Func func() int
	var v1 Func = nil
	var v2 Func = nil
	fmt.Println(is.Eq(v1, v2)) // true
	f1 := func() int { return 1 }
	f2 := f1
	f3 := func() int { return 1 }
	fmt.Println(is.Eq(f1, f2)) // false
	fmt.Println(is.Eq(f1, f3)) // false

}
Output:

true
false
true
true
false
true
false
true
false
true
false
false

func False

func False(v bool) bool

False returns true if the value is false.

Parameters:

  • v: The boolean value to check

Returns:

  • bool: true if the value is false

Example:

is.False(true)     // false
is.False(false)    // true
Example

ExampleFalse demonstrates the False function

package main

import (
	"fmt"

	"github.com/go4x/goal/is"
)

func main() {
	fmt.Println(is.False(true))  // false
	fmt.Println(is.False(false)) // true
}
Output:

false
true

func Gt

func Gt[T cmp.Ordered](a, b T) bool

Gt checks if a is greater than b. This function requires types that support ordering (numbers, strings, etc.).

Parameters:

  • a: The first value to compare
  • b: The second value to compare

Returns:

  • bool: true if a > b, false otherwise

Example:

is.Gt(42, 10)        // true
is.Gt("z", "a")      // true
is.Gt(5, 10)         // false

func Gte

func Gte[T cmp.Ordered](a, b T) bool

Gte checks if a is greater than or equal to b. This function requires types that support ordering (numbers, strings, etc.).

Parameters:

  • a: The first value to compare
  • b: The second value to compare

Returns:

  • bool: true if a >= b, false otherwise

Example:

is.Gte(42, 42)       // true
is.Gte(42, 10)       // true
is.Gte(5, 10)        // false

func Lt

func Lt[T cmp.Ordered](a, b T) bool

Lt checks if a is less than b. This function requires types that support ordering (numbers, strings, etc.).

Parameters:

  • a: The first value to compare
  • b: The second value to compare

Returns:

  • bool: true if a < b, false otherwise

Example:

is.Lt(5, 10)         // true
is.Lt("a", "z")      // true
is.Lt(42, 10)        // false

func Lte

func Lte[T cmp.Ordered](a, b T) bool

Lte checks if a is less than or equal to b. This function requires types that support ordering (numbers, strings, etc.).

Parameters:

  • a: The first value to compare
  • b: The second value to compare

Returns:

  • bool: true if a <= b, false otherwise

Example:

is.Lte(42, 42)       // true
is.Lte(5, 10)        // true
is.Lte(42, 10)       // false

func Neq

func Neq[T comparable](a, b T) bool

Neq checks if two values are not equal. This is the logical negation of Equal.

Parameters:

  • a: The first value to compare
  • b: The second value to compare

Returns:

  • bool: true if the values are not equal, false otherwise

Example:

is.Neq(42, 43)     // true
is.Neq("hello", "hello") // false
is.Neq(0, 1)       // true

func Nil

func Nil(v any) bool

Nil checks if the value is nil (for pointer, slice, map, channel, function, interface). This function uses reflection to properly check nil values for reference types.

Parameters:

  • v: The value to check (can be any type)

Returns:

  • bool: true if the value is nil

Example:

var ptr *int
is.Nil(ptr)        // true
is.Nil(nil)        // true
is.Nil([]int{})    // false (empty slice is not nil)
Example

ExampleIsNil demonstrates the IsNil function

package main

import (
	"fmt"

	"github.com/go4x/goal/is"
)

func main() {
	var ptr *int
	fmt.Println(is.Nil(ptr))     // true
	fmt.Println(is.Nil(nil))     // true
	fmt.Println(is.Nil([]int{})) // false (empty slice is not nil)

	val := 42
	ptr = &val
	fmt.Println(is.Nil(ptr)) // false
}
Output:

true
true
false
false

func Not

func Not(v bool) bool

Not returns the logical negation of the value. Is is an alias for False.

Parameters:

  • v: The boolean value to negate

Returns:

  • bool: true if the value is false, false if the value is true

Example:

is.Not(true)     // false
is.Not(false)    // true
Example

ExampleNot demonstrates the Not function

package main

import (
	"fmt"

	"github.com/go4x/goal/is"
)

func main() {
	supported := true
	if is.Not(supported) {
		fmt.Println("not supported")
	} else {
		fmt.Println("supported")
	}
}
Output:

supported

func NotEmpty

func NotEmpty(v any) bool

NotEmpty checks if the value is not empty. This is the logical negation of IsEmpty.

Parameters:

  • v: The value to check (can be any type)

Returns:

  • bool: true if the value is not empty

Example:

is.NotEmpty("hello")     // true
is.NotEmpty([]int{1, 2}) // true
is.NotEmpty(42)          // true
is.NotEmpty("")          // false
is.NotEmpty([]int{})     // false

func NotNil

func NotNil(v any) bool

NotNil checks if the value is not nil. This is the logical negation of IsNil.

Parameters:

  • v: The value to check (can be any type)

Returns:

  • bool: true if the value is not nil

Example:

ptr := &42
is.NotNil(ptr)     // true
is.NotNil([]int{}) // true (empty slice is not nil)
is.NotNil(nil)     // false

func NotSame

func NotSame[T comparable](a, b T) bool

NotSame checks if two values are not the same. This is the logical negation of Same.

Parameters:

  • a: The first value to compare
  • b: The second value to compare

Returns:

  • bool: true if the values are not the same, false otherwise

Example:

is.NotSame(42, 43)     // true
is.NotSame("hello", "hello") // false
is.NotSame(0, 1)       // true

func NotZero

func NotZero[T comparable](v T) bool

NotZero checks if the value is not the zero value for its type. This is the logical negation of IsZero.

Parameters:

  • v: The value to check

Returns:

  • bool: true if the value is not the zero value for its type

Example:

is.NotZero(42)     // true
is.NotZero("hello") // true
is.NotZero(0)      // false
is.NotZero("")     // false

func Same

func Same[T comparable](a, b T) bool

Same checks if two values are the same. This is an alias for Eq, using the == operator for comparison. Same emphasizes that the values are identical, not just equal.

Parameters:

  • a: The first value to compare
  • b: The second value to compare

Returns:

  • bool: true if the values are the same, false otherwise

Example:

is.Same(42, 42)        // true
is.Same("hello", "hi") // false
is.Same(0, 0)          // true

var ptr1, ptr2 *int
val := 42
ptr1 = &val
ptr2 = &val
is.Same(ptr1, ptr2)    // true (same pointer)

func True

func True(v bool) bool

True returns true if the value is true.

Parameters:

  • v: The boolean value to check

Returns:

  • bool: true if the value is true

Example:

is.True(true)     // true
is.True(false)    // false

func Zero

func Zero[T comparable](v T) bool

Zero checks if the value is the zero value for its type. Zero values are: 0 for numeric types, "" for strings, false for bools, nil for pointers/slices/maps/channels/functions/interfaces.

Parameters:

  • v: The value to check

Returns:

  • bool: true if the value is the zero value for its type

Example:

is.Zero(0)        // true
is.Zero("")        // true
is.Zero(false)     // true
is.Zero(42)        // false
is.Zero("hello")   // false
Example

ExampleIsZero demonstrates the IsZero function

package main

import (
	"fmt"

	"github.com/go4x/goal/is"
)

func main() {
	fmt.Println(is.Zero(0))       // true
	fmt.Println(is.Zero(""))      // true
	fmt.Println(is.Zero(false))   // true
	fmt.Println(is.Zero(42))      // false
	fmt.Println(is.Zero("hello")) // false
}
Output:

true
true
true
false
false

Types

This section is empty.

Jump to

Keyboard shortcuts

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