wtype

package module
v1.10.0 Latest Latest
Warning

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

Go to latest
Published: Jan 9, 2026 License: MIT Imports: 16 Imported by: 1

README

WTYPE

zread

TODO

  • add lint
Cache
  • add example
  • add test
SafeCache
  • add example
  • add test
Set
  • add example
  • add test
  • json.Marshal
  • json.Unmarshal
SafeSet
  • add example
  • add test
  • json.Marshal (need use *SafeSet)
  • json.Unmarshal
Context
  • add example
  • add test
GormSlice
  • add example
  • add test
SyncMap
  • add example
  • add test
  • json.Marshal (need use *SyncMap)
  • json.Unmarshal
String & StringSlice
  • add example
  • add test
EventCenter
  • add example
  • add test
  • add Once

Documentation

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func Assert added in v1.10.0

func Assert[T any](a any) (T, bool)

Assert asserts that a is of type T.

If successful, it returns the value of type T and true.
If it fails, it returns the zero value of type T and false.
Example
package main

import (
	"fmt"

	"github.com/wuchieh/wtype"
)

func main() {
	a := any(int32(5))
	fmt.Println(wtype.Assert[int32](a))
	fmt.Println(wtype.Assert[int](a))

}
Output:

5 true
0 false

func ByteToString added in v1.9.3

func ByteToString(b []byte) string

ByteToString returns the string of a byte slice

func ContextDo added in v1.9.4

func ContextDo(ctx IContext)

func ContextIsTimeout added in v1.10.0

func ContextIsTimeout(ctx context.Context) bool

ContextIsTimeout checks if the context has timed out.

Example
package main

import (
	"context"
	"fmt"
	"time"

	"github.com/wuchieh/wtype"
)

func main() {
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Millisecond)
	defer cancel()

	fmt.Println(wtype.ContextIsTimeout(ctx))

	time.Sleep(50 * time.Millisecond)

	fmt.Println(wtype.ContextIsTimeout(ctx))

}
Output:

false
true

func DoShared added in v1.6.2

func DoShared[T any](key string, fn func() (T, error)) (T, error)

DoShared executes the given function fn associated with the provided key. If multiple calls with the same key are made concurrently, fn will only be executed once, and the result will be shared among all callers.

func DoShared2 added in v1.8.0

func DoShared2[T any](fn func() (T, error)) (T, error)

DoShared2 executes the given function fn associated with the provided key.

func DoSharedChan added in v1.6.2

func DoSharedChan[T any](key string, fn func() (T, error)) <-chan SharedChanResult[T]

DoSharedChan is the channel-based variant of DoShared. It executes the given function fn associated with the provided key. If multiple calls with the same key are made concurrently, fn will only be executed once, and the result will be delivered through the returned channel.

func DoSharedChan2 added in v1.8.0

func DoSharedChan2[T any](fn func() (T, error)) <-chan SharedChanResult[T]

DoSharedChan2 is the channel-based variant of DoShared2.

func DoSharedForget added in v1.6.2

func DoSharedForget(key string)

DoSharedForget removes the entry for the given key from the shared group, allowing subsequent calls with the same key to re-execute the function fn instead of receiving a shared result.

func Fallback added in v1.7.1

func Fallback[T any](data ...T) T

Fallback returns the first non-zero value from the given arguments. If all values are zero, it returns the zero value of type T.

Example
package main

import (
	"fmt"

	"github.com/wuchieh/wtype"
)

func main() {
	r1 := wtype.Fallback(0, 5, 10)                         // returns 5
	r2 := wtype.Fallback("", "hello", "hi")                // returns "hello"
	r3 := wtype.Fallback(false, false, true)               // returns true
	r4 := wtype.Fallback(0, 0, 0)                          // returns 0
	r5 := wtype.Fallback([]int(nil), []int{}, []int{1, 2}) // returns []int{} (non-nil, not zero)

	fmt.Println(r1)
	fmt.Println(r2)
	fmt.Println(r3)
	fmt.Println(r4)
	fmt.Println(r5)

}
Output:

5
hello
true
0
[]

func MapConvert added in v1.10.0

func MapConvert[K, V, K2, V2 comparable](m map[K]V, f func(K, V) (K2, V2, bool)) map[K2]V2

MapConvert converts map[K]V to map[K2]V2.

If the conversion function returns false, the element will be skipped.
Example
package main

import (
	"fmt"
	"sort"

	"github.com/wuchieh/wtype"
)

func main() {
	m := map[string]int{
		"a": 1,
		"b": 2,
		"c": 3,
	}

	m2 := wtype.MapConvert(m, func(k string, v int) (int, string, bool) {
		if v%2 == 0 {
			return 0, "", false
		}
		return v, k, true
	})

	// map output order is random, so we sort keys for stable output
	keys := make([]int, 0, len(m2))
	for k := range m2 {
		keys = append(keys, k)
	}
	sort.Ints(keys)

	for _, k := range keys {
		fmt.Printf("%d:%s ", k, m2[k])
	}
	fmt.Println()

}
Output:

1:a 3:c

func MapReverse added in v1.10.0

func MapReverse[K, V comparable](m map[K]V) map[V]K

MapReverse swaps the keys and values of map[K]V.

Example
package main

import (
	"fmt"
	"sort"

	"github.com/wuchieh/wtype"
)

func main() {
	m := map[string]int{
		"a": 1,
		"b": 2,
		"c": 3,
	}

	m2 := wtype.MapReverse(m)

	// map output order is random, so we sort keys for stable output
	keys := make([]int, 0, len(m2))
	for k := range m2 {
		keys = append(keys, k)
	}
	sort.Ints(keys)

	for _, k := range keys {
		fmt.Printf("%d:%s ", k, m2[k])
	}
	fmt.Println()

}
Output:

1:a 2:b 3:c

func SliceConvert added in v1.6.0

func SliceConvert[T, K any](s []T, f func(T) K) []K

SliceConvert converts a slice of type T to a slice of type K

func SliceConvert2 added in v1.8.0

func SliceConvert2[T, K any](s []T, f func(int, T) (K, bool)) []K

SliceConvert2 converts a slice of type T to a slice of type K

If the function returns false, the element will be skipped.
Example
package main

import (
	"fmt"

	"github.com/wuchieh/wtype"
)

func main() {
	var data []int
	for i := 0; i < 10; i++ {
		data = append(data, i)
	}

	result := wtype.SliceConvert2(data, func(i int, v int) (int, bool) {
		if v%2 == 0 {
			return v, true
		}
		return 0, false
	})

	fmt.Println(result)

}
Output:

[0 2 4 6 8]

func SlicePointConvert added in v1.6.0

func SlicePointConvert[T any](s []T) []*T

SlicePointConvert converts a slice of type *T to a slice of type K

func SliceToMap added in v1.6.0

func SliceToMap[T any, K comparable](slice []T, getKey func(int, T) K) map[K]T

SliceToMap converts a slice to a map

func SliceUnPointConvert added in v1.6.0

func SliceUnPointConvert[T any](s []*T) []T

SliceUnPointConvert converts a slice of type *T to a slice of type K

func Stack added in v1.7.3

func Stack(skip int, reverse ...bool) []byte

Stack returns a nicely formatted stack frame, skipping skip frames.

func StackString added in v1.9.4

func StackString(skip int, reverse ...bool) string

StackString returns a nicely formatted stack frame, skipping skip frames.

func StringLen added in v1.9.2

func StringLen(s string) int

StringLen returns the length of a string in runes

func StringSlice added in v1.6.0

func StringSlice(s string, start int, end ...int) string

StringSlice returns a substring of a string

func StringToByte added in v1.9.3

func StringToByte(s string) []byte

StringToByte returns the byte slice of a string

func StructStringTrim added in v1.6.0

func StructStringTrim(v any)

StructStringTrim removes leading and trailing whitespace from a struct

Types

type Cache

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

func NewCache

func NewCache[T any](d time.Duration, data ...T) *Cache[T]

NewCache creates a new cache.

If d is 0, the cache will never expire.
Example

ExampleNewCache demonstrates creating a new cache with different configurations

package main

import (
	"fmt"
	"time"

	"github.com/wuchieh/wtype"
)

func main() {
	// Create a cache that expires after 5 seconds
	cache := wtype.NewCache[string](5 * time.Second)
	fmt.Printf("Empty cache: %q\n", cache.Get())

	// Create a cache with initial data
	cacheWithData := wtype.NewCache[int](3*time.Second, 42)
	fmt.Printf("Cache with initial data: %d\n", cacheWithData.Get())

	// Create a cache that never expires
	permanentCache := wtype.NewCache[string](0)
	permanentCache.Set("permanent data")
	fmt.Printf("Permanent cache: %q\n", permanentCache.Get())

}
Output:

Empty cache: ""
Cache with initial data: 42
Permanent cache: "permanent data"
Example (NeverExpire)

ExampleNewCache_neverExpire demonstrates creating a cache that never expires

package main

import (
	"fmt"
	"time"

	"github.com/wuchieh/wtype"
)

func main() {
	// Create cache with zero duration (never expires)
	cache := wtype.NewCache[string](0, "permanent data")
	fmt.Println(cache.Get())

	time.Sleep(100 * time.Millisecond)
	fmt.Println(cache.Get())

}
Output:

permanent data
permanent data

func (*Cache[T]) Get

func (c *Cache[T]) Get() T
Example

ExampleCache_Get demonstrates getting data from the cache

package main

import (
	"fmt"
	"time"

	"github.com/wuchieh/wtype"
)

func main() {
	cache := wtype.NewCache[int](1 * time.Second)

	// Get from empty cache (zero value)
	fmt.Printf("Empty cache: %d\n", cache.Get())

	// Set and get data
	cache.Set(100)
	fmt.Printf("With data: %d\n", cache.Get())

}
Output:

Empty cache: 0
With data: 100

func (*Cache[T]) ResetTimer added in v1.1.0

func (c *Cache[T]) ResetTimer()

ResetTimer resets the timer of the cache.

Example

ExampleCache_ResetTimer demonstrates resetting the cache timer

package main

import (
	"fmt"
	"time"

	"github.com/wuchieh/wtype"
)

func main() {
	cache := wtype.NewCache[string](100 * time.Millisecond)
	cache.Set("data")

	// Wait a bit, then reset timer
	time.Sleep(50 * time.Millisecond)
	cache.ResetTimer()
	fmt.Printf("Timer reset, data: %q\n", cache.Get())

	// Data should still be available after original time would have expired
	time.Sleep(75 * time.Millisecond)
	fmt.Printf("After partial wait, data: %q\n", cache.Get())

}
Output:

Timer reset, data: "data"
After partial wait, data: "data"

func (*Cache[T]) Set

func (c *Cache[T]) Set(data T)

Set sets the data of the cache.

Example

ExampleCache_Set demonstrates setting data in the cache

package main

import (
	"fmt"
	"time"

	"github.com/wuchieh/wtype"
)

func main() {
	cache := wtype.NewCache[string](2 * time.Second)

	cache.Set("Hello, World!")
	fmt.Printf("After set: %q\n", cache.Get())

	// Setting new data resets the timer
	cache.Set("Updated data")
	fmt.Printf("After update: %q\n", cache.Get())

}
Output:

After set: "Hello, World!"
After update: "Updated data"

func (*Cache[T]) SetDuration

func (c *Cache[T]) SetDuration(d time.Duration)

SetDuration sets the duration of the cache.

Example

ExampleCache_SetDuration demonstrates changing cache duration

package main

import (
	"fmt"
	"time"

	"github.com/wuchieh/wtype"
)

func main() {
	cache := wtype.NewCache[string](1 * time.Second)
	cache.Set("test data")

	// Change duration to 5 seconds
	cache.SetDuration(5 * time.Second)
	fmt.Printf("Duration changed, data: %q\n", cache.Get())

	// Change to permanent (0 duration)
	cache.SetDuration(0)
	fmt.Printf("Permanent cache, data: %q\n", cache.Get())

}
Output:

Duration changed, data: "test data"
Permanent cache, data: "test data"

func (*Cache[T]) StopTimer added in v1.1.0

func (c *Cache[T]) StopTimer()

StopTimer stops the timer of the cache.

The data will be retained permanently.
Example

ExampleCache_StopTimer demonstrates stopping the cache timer

package main

import (
	"fmt"
	"time"

	"github.com/wuchieh/wtype"
)

func main() {
	cache := wtype.NewCache[string](100 * time.Millisecond)
	cache.Set("important data")

	// Stop the timer to prevent expiration
	cache.StopTimer()
	fmt.Printf("Timer stopped, data: %q\n", cache.Get())

	// Wait beyond the original expiration time
	time.Sleep(200 * time.Millisecond)
	fmt.Printf("After wait, data still: %q\n", cache.Get())

}
Output:

Timer stopped, data: "important data"
After wait, data still: "important data"

type Context added in v1.4.0

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

func AddHandler added in v1.4.0

func AddHandler[T any](ctx Context[T], handlers ...func(*Context[T])) Context[T]

func NewContext added in v1.4.0

func NewContext[T any](c T) Context[T]
Example
package main

import (
	"fmt"

	"github.com/wuchieh/wtype"
)

func main() {
	ctx := wtype.NewContext(0)

	type tempCtx = wtype.Context[int]

	ctx = wtype.AddHandler(ctx,
		func(c *tempCtx) {
			fmt.Println("1")
			c.Next()
			fmt.Println("3")
			fmt.Println("Data:", c.C)
		},
		func(c *tempCtx) {
			fmt.Println("2")
			c.C++
		},
	)

	ctx.Do()
	fmt.Println("==========")
	ctx.Do()

}
Output:

1
2
3
Data: 1
==========
1
2
3
Data: 1

func (*Context[T]) Abort added in v1.4.0

func (c *Context[T]) Abort()

func (*Context[T]) Deadline added in v1.10.0

func (c *Context[T]) Deadline() (deadline time.Time, ok bool)

func (*Context[T]) Do added in v1.9.4

func (c *Context[T]) Do()

func (*Context[T]) DoBefore added in v1.9.4

func (c *Context[T]) DoBefore() IContext

func (*Context[T]) Done added in v1.10.0

func (c *Context[T]) Done() <-chan struct{}

func (*Context[T]) Err added in v1.10.0

func (c *Context[T]) Err() error

func (*Context[T]) Get added in v1.4.0

func (c *Context[T]) Get(s string) (any, bool)

func (*Context[T]) IsAborted added in v1.4.0

func (c *Context[T]) IsAborted() bool

func (*Context[T]) Next added in v1.4.0

func (c *Context[T]) Next()

func (*Context[T]) Set added in v1.4.0

func (c *Context[T]) Set(s string, a any)

func (*Context[T]) Value added in v1.10.0

func (c *Context[T]) Value(key any) any

type CustomCache added in v1.1.3

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

CustomCache

Cache objects with fully customizable functions

func NewCustomCache added in v1.1.3

func NewCustomCache[T any](
	duration time.Duration,
	setFunc func(T, time.Duration),
	getFunc func() T,
	beforeSetDuration func(duration time.Duration) time.Duration,
	resetTimer func(time.Duration),
	stopTimer func(),
) *CustomCache[T]

func (*CustomCache[T]) Get added in v1.1.3

func (c *CustomCache[T]) Get() T

func (*CustomCache[T]) ResetTimer added in v1.1.3

func (c *CustomCache[T]) ResetTimer()

func (*CustomCache[T]) Set added in v1.1.3

func (c *CustomCache[T]) Set(t T)

func (*CustomCache[T]) SetDuration added in v1.1.3

func (c *CustomCache[T]) SetDuration(duration time.Duration)

func (*CustomCache[T]) StopTimer added in v1.1.3

func (c *CustomCache[T]) StopTimer()

type EventCenter added in v1.9.0

type EventCenter struct {
	// contains filtered or unexported fields
}

EventCenter manages event registration, emission, and removal. It is safe for concurrent use.

func NewEventCenter added in v1.9.0

func NewEventCenter() *EventCenter

NewEventCenter creates and returns a new EventCenter instance.

Example
package main

import (
	"fmt"

	"github.com/wuchieh/wtype"
)

func main() {
	center := wtype.NewEventCenter()

	creatFunc := func(i int) func(data ...any) {
		return func(data ...any) {
			fmt.Println(i)
		}
	}

	run1 := creatFunc(1)
	run2 := creatFunc(2)
	run3 := creatFunc(3)
	run4 := creatFunc(4)

	center.On("run", run1)
	center.On("run", run2)
	center.On("run", run3)
	center.On("run", run4)

	center.Emit("run")
	center.Off("run", run3)
	fmt.Println("-----")
	center.Emit("run")
	fmt.Println("-----")

	var onceRun func(data ...any)
	onceRun = func(data ...any) {
		fmt.Println("once")
		center.Off("once", onceRun)
	}
	center.On("once", onceRun)
	center.Emit("once")
	center.Emit("once")

}
Output:

1
2
3
4
-----
1
2
4
-----
once

func (*EventCenter) Emit added in v1.9.0

func (e *EventCenter) Emit(key string, data ...any)

Emit triggers all handlers registered for the given event key. The data arguments are passed to each handler in order. Handlers are copied before invocation to avoid issues if the list is modified during execution.

func (*EventCenter) Off added in v1.9.0

func (e *EventCenter) Off(key string, handler EventHandler)

Off removes a specific handler for the given event key. It compares handlers by their underlying function pointer value.

func (*EventCenter) On added in v1.9.0

func (e *EventCenter) On(key string, handler EventHandler)

On registers a new handler for the given event key. Multiple handlers can be registered under the same key.

func (*EventCenter) Once added in v1.9.5

func (e *EventCenter) Once(key string, handler EventHandler)

Once registers a handler that will only be executed once for the given event key. After the first execution, the handler is automatically removed.

Example
package main

import (
	"fmt"

	"github.com/wuchieh/wtype"
)

func main() {
	ec := wtype.NewEventCenter()
	ec.Once("once", func(data ...any) {
		fmt.Println(data...)
	})

	ec.Emit("once", "first")
	ec.Emit("once", "second")

}
Output:

first

type EventHandler added in v1.9.0

type EventHandler func(data ...any)

EventHandler defines a function type for event callbacks. The function can accept any number of arguments of any type.

type FileSize added in v1.7.2

type FileSize int64

FileSize represents file size units in bytes.

Example
package main

import (
	"fmt"

	"github.com/wuchieh/wtype"
)

func main() {
	fmt.Println(wtype.B)
	fmt.Println(wtype.KB)
	fmt.Println(wtype.MB)
	fmt.Println(wtype.GB)
	fmt.Println(wtype.TB)
	fmt.Println(wtype.TB + wtype.GB*100)

}
Output:

1B
1.0KB
1.0MB
1.0GB
1.0TB
1.1TB
const (
	B  FileSize = 1 << (10 * iota) // 1 B
	KB                             // 1 KB = 1024 B
	MB                             // 1 MB = 1024 KB
	GB                             // 1 GB = 1024 MB
	TB                             // 1 TB = 1024 GB
)

func (FileSize) String added in v1.7.2

func (s FileSize) String() string

type GormSlice added in v1.1.2

type GormSlice[T any] []T

func (GormSlice[T]) GormDBDataType added in v1.1.2

func (GormSlice[T]) GormDBDataType(db *gorm.DB, _ *schema.Field) string

func (*GormSlice[T]) Scan added in v1.1.2

func (g *GormSlice[T]) Scan(value any) error

func (GormSlice[T]) ToSlice added in v1.2.1

func (g GormSlice[T]) ToSlice() []T

ToSlice convert to slice

use for gorm where

func (GormSlice[T]) Value added in v1.1.2

func (g GormSlice[T]) Value() (driver.Value, error)

type ICache

type ICache[T any] interface {
	Set(T)
	Get() T
	SetDuration(time.Duration)
	ResetTimer()
	StopTimer()
}

type IContext added in v1.4.0

type IContext interface {
	Next()
	Abort()
	IsAborted() bool
	Get(string) (any, bool)
	Set(string, any)
}

type IContextDoBefore added in v1.9.4

type IContextDoBefore interface {
	DoBefore() IContext
}

type IMap added in v1.9.4

type IMap[K comparable, V any] interface {
	Load(key K) (value V, ok bool)
	Store(key K, value V)
	LoadOrStore(key K, value V) (actual V, loaded bool)
	LoadAndDelete(key K) (value V, loaded bool)
	Delete(K)
	Swap(key K, value V) (previous V, loaded bool)
	CompareAndSwap(key K, old, new V) (swapped bool)
	CompareAndDelete(key K, old V) (deleted bool)
	Range(func(key K, value V) (shouldContinue bool))
	Clear()
}

type ISet added in v1.3.0

type ISet[T comparable] interface {
	Add(T)
	Get() []T
	Len() int
	Remove(T)
	Clear()
	Range(func(T) bool)
	Contains(T) bool
	Values() []T
}

type SQLJSON added in v1.9.1

type SQLJSON = SqlJSON

SqlJSON implements sql.Scanner interface

type SQLJSON2 added in v1.9.1

type SQLJSON2[T any] = SqlJSON2[T]

type SafeCache

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

func NewSafeCache

func NewSafeCache[T any](d time.Duration, data ...T) *SafeCache[T]

NewSafeCache creates a new safe cache.

Example

ExampleNewSafeCache demonstrates creating a new thread-safe cache

package main

import (
	"fmt"
	"time"

	"github.com/wuchieh/wtype"
)

func main() {
	// Create a safe cache that expires after 5 seconds
	safeCache := wtype.NewSafeCache[string](5 * time.Second)
	fmt.Printf("Empty safe cache: %q\n", safeCache.Get())

	// Create a safe cache with initial data
	safeCacheWithData := wtype.NewSafeCache[int](3*time.Second, 42)
	fmt.Printf("Safe cache with initial data: %d\n", safeCacheWithData.Get())

	// Create a safe cache that never expires
	permanentSafeCache := wtype.NewSafeCache[string](0)
	permanentSafeCache.Set("permanent safe data")
	fmt.Printf("Permanent safe cache: %q\n", permanentSafeCache.Get())

}
Output:

Empty safe cache: ""
Safe cache with initial data: 42
Permanent safe cache: "permanent safe data"

func (*SafeCache[T]) Get

func (s *SafeCache[T]) Get() T

Get gets the data of the cache.

Example

ExampleSafeCache_Get demonstrates getting data from the thread-safe cache

package main

import (
	"fmt"
	"time"

	"github.com/wuchieh/wtype"
)

func main() {
	safeCache := wtype.NewSafeCache[int](1 * time.Second)

	// Get from empty cache (zero value)
	fmt.Printf("Empty safe cache: %d\n", safeCache.Get())

	// Set and get data
	safeCache.Set(100)
	fmt.Printf("With data: %d\n", safeCache.Get())

}
Output:

Empty safe cache: 0
With data: 100

func (*SafeCache[T]) ResetTimer added in v1.1.0

func (s *SafeCache[T]) ResetTimer()

ResetTimer resets the timer of the cache.

func (*SafeCache[T]) Set

func (s *SafeCache[T]) Set(data T)

Set sets the data of the cache.

Example

ExampleSafeCache_Set demonstrates setting data in the thread-safe cache

package main

import (
	"fmt"
	"time"

	"github.com/wuchieh/wtype"
)

func main() {
	safeCache := wtype.NewSafeCache[string](2 * time.Second)

	safeCache.Set("Hello, Safe World!")
	fmt.Printf("After set: %q\n", safeCache.Get())

	// Setting new data resets the timer
	safeCache.Set("Updated safe data")
	fmt.Printf("After update: %q\n", safeCache.Get())

}
Output:

After set: "Hello, Safe World!"
After update: "Updated safe data"

func (*SafeCache[T]) SetDuration

func (s *SafeCache[T]) SetDuration(duration time.Duration)

SetDuration sets the duration of the cache.

func (*SafeCache[T]) StopTimer added in v1.1.0

func (s *SafeCache[T]) StopTimer()

StopTimer stops the timer of the cache.

The data will be retained permanently.

func (*SafeCache[T]) Use added in v1.1.0

func (s *SafeCache[T]) Use(f func(T) T)

Use uses the data of the cache.

The data will be updated after the function is called.
Example

ExampleSafeCache_Use demonstrates using the Use method to update cache data

package main

import (
	"fmt"
	"time"

	"github.com/wuchieh/wtype"
)

func main() {
	safeCache := wtype.NewSafeCache[int](5 * time.Second)
	safeCache.Set(10)

	fmt.Printf("Before Use: %d\n", safeCache.Get())

	// Use function to double the value
	safeCache.Use(func(current int) int {
		return current * 2
	})

	fmt.Printf("After Use (doubled): %d\n", safeCache.Get())

	// Use function to add 5
	safeCache.Use(func(current int) int {
		return current + 5
	})

	fmt.Printf("After Use (added 5): %d\n", safeCache.Get())

}
Output:

Before Use: 10
After Use (doubled): 20
After Use (added 5): 25

func (*SafeCache[T]) Use2 added in v1.1.1

func (s *SafeCache[T]) Use2(f func(T) (T, error)) error

Use2 uses the data of the cache.

If the data is not set, the function will be called and the result will be set.
Example

ExampleSafeCache_Use2 demonstrates using the Use2 method with error handling

package main

import (
	"fmt"
	"time"

	"github.com/wuchieh/wtype"
)

func main() {
	safeCache := wtype.NewSafeCache[string](5 * time.Second)
	safeCache.Set("hello")

	fmt.Printf("Before Use2: %q\n", safeCache.Get())

	// Use2 function to convert to uppercase
	err := safeCache.Use2(func(current string) (string, error) {
		if current == "" {
			return "", fmt.Errorf("empty string")
		}
		return fmt.Sprintf("%s WORLD", current), nil
	})

	if err != nil {
		fmt.Printf("Error: %v\n", err)
	} else {
		fmt.Printf("After Use2 (success): %q\n", safeCache.Get())
	}

	// Use2 function that returns an error
	safeCache.Set("")
	err = safeCache.Use2(func(current string) (string, error) {
		if current == "" {
			return "", fmt.Errorf("cannot process empty string")
		}
		return current + " processed", nil
	})
	if err != nil {
		fmt.Printf("Error occurred: %v\n", err)
		fmt.Printf("Data unchanged: %q\n", safeCache.Get())
	}

}
Output:

Before Use2: "hello"
After Use2 (success): "hello WORLD"
Error occurred: cannot process empty string
Data unchanged: ""

type SafeSet added in v1.3.0

type SafeSet[T comparable] struct {
	// contains filtered or unexported fields
}

SafeSet is a thread-safe version of Set.

func NewSafeSet added in v1.3.0

func NewSafeSet[T comparable](val ...T) *SafeSet[T]

NewSafeSet creates a new empty SafeSet.

Example
package main

import (
	"fmt"

	"github.com/wuchieh/wtype"
)

func main() {
	ids := wtype.NewSafeSet(1, 2, 3, 1, 2, 3)
	ids.Range(func(i int) bool {
		ids.Add(i + 2)
		return true
	})
	ids.Remove(4)

	fmt.Println(ids.Len())
	fmt.Println(ids.Contains(4))
	fmt.Println(ids.Contains(5))

}
Output:

4
false
true

func (*SafeSet[T]) Add added in v1.3.0

func (s *SafeSet[T]) Add(data T)

Add adds an element to the set.

func (*SafeSet[T]) Clear added in v1.3.0

func (s *SafeSet[T]) Clear()

Clear removes all elements from the set.

func (*SafeSet[T]) Contains added in v1.3.0

func (s *SafeSet[T]) Contains(data T) bool

Contains checks if an element exists in the set.

func (*SafeSet[T]) Get added in v1.3.0

func (s *SafeSet[T]) Get() []T

Get returns all elements in the set as a slice. The order of elements is not guaranteed.

func (*SafeSet[T]) Len added in v1.3.0

func (s *SafeSet[T]) Len() int

Len returns the number of elements in the set.

func (*SafeSet[T]) MarshalJSON added in v1.9.4

func (s *SafeSet[T]) MarshalJSON() ([]byte, error)

MarshalJSON implementation json.Marshal

func (*SafeSet[T]) Range added in v1.3.0

func (s *SafeSet[T]) Range(f func(T) bool)

Range iterates over the set and calls f for each element. If f returns false, the iteration stops. The iteration is performed under a read lock.

func (*SafeSet[T]) Remove added in v1.3.0

func (s *SafeSet[T]) Remove(data T)

Remove removes an element from the set.

func (*SafeSet[T]) SortValues added in v1.9.4

func (s *SafeSet[T]) SortValues(cmp func(a T, b T) bool) []T

SortValues sort the set values

func (*SafeSet[T]) UnmarshalJSON added in v1.9.4

func (s *SafeSet[T]) UnmarshalJSON(bytes []byte) error

UnmarshalJSON implementation json.Unmarshal

func (*SafeSet[T]) Values added in v1.6.0

func (s *SafeSet[T]) Values() []T

Values returns all elements in the set as a slice.

The order of elements is not guaranteed.

type Set added in v1.3.0

type Set[T comparable] struct {
	// contains filtered or unexported fields
}

Set is a generic, non-thread-safe set implementation.

Example (EmptySet)

ExampleSet_emptySet demonstrates working with empty sets

package main

import (
	"fmt"

	"github.com/wuchieh/wtype"
)

func main() {
	set := wtype.NewSet[string]()

	fmt.Printf("Empty set length: %d\n", set.Len())
	fmt.Printf("Contains anything: %t\n", set.Contains("anything"))

	// Get from empty set
	elements := set.Get()
	fmt.Printf("Elements in empty set: %v\n", elements)

	// Range over empty set
	fmt.Println("Ranging over empty set:")
	set.Range(func(element string) bool {
		fmt.Printf("This won't print: %s\n", element)
		return true
	})
	fmt.Println("Range completed")

}
Output:

Empty set length: 0
Contains anything: false
Elements in empty set: []
Ranging over empty set:
Range completed
Example (SetOperations)

ExampleSet_setOperations demonstrates common set operations

package main

import (
	"fmt"
	"sort"

	"github.com/wuchieh/wtype"
)

func main() {
	// Create two sets
	set1 := wtype.NewSet[int]()
	set1.Add(1)
	set1.Add(2)
	set1.Add(3)

	set2 := wtype.NewSet[int]()
	set2.Add(3)
	set2.Add(4)
	set2.Add(5)

	// Union: elements in either set
	union := wtype.NewSet[int]()
	set1.Range(func(element int) bool {
		union.Add(element)
		return true
	})
	set2.Range(func(element int) bool {
		union.Add(element)
		return true
	})

	// Intersection: elements in both sets
	intersection := wtype.NewSet[int]()
	set1.Range(func(element int) bool {
		if set2.Contains(element) {
			intersection.Add(element)
		}
		return true
	})

	unionElements := union.Get()
	sort.Ints(unionElements)
	fmt.Printf("Union: %v\n", unionElements)

	intersectionElements := intersection.Get()
	sort.Ints(intersectionElements)
	fmt.Printf("Intersection: %v\n", intersectionElements)

}
Output:

Union: [1 2 3 4 5]
Intersection: [3]
Example (UniqueWords)

ExampleSet_uniqueWords demonstrates practical usage for finding unique words

package main

import (
	"fmt"
	"sort"
	"strings"

	"github.com/wuchieh/wtype"
)

func main() {
	text := "the quick brown fox jumps over the lazy dog the fox is quick"
	words := strings.Fields(text)

	// Use set to find unique words
	uniqueWords := wtype.NewSet[string]()
	for _, word := range words {
		uniqueWords.Add(word)
	}

	fmt.Printf("Total words: %d\n", len(words))
	fmt.Printf("Unique words: %d\n", uniqueWords.Len())

	// Get unique words and sort for consistent output
	unique := uniqueWords.Get()
	sort.Strings(unique)
	fmt.Printf("Unique word list: %v\n", unique)

}
Output:

Total words: 13
Unique words: 9
Unique word list: [brown dog fox is jumps lazy over quick the]
Example (WithDifferentTypes)

ExampleSet_withDifferentTypes demonstrates sets with different data types

package main

import (
	"fmt"

	"github.com/wuchieh/wtype"
)

func main() {
	// String set
	stringSet := wtype.NewSet[string]()
	stringSet.Add("Go")
	stringSet.Add("Python")
	stringSet.Add("Java")
	fmt.Printf("Programming languages: %d\n", stringSet.Len())

	// Int set
	intSet := wtype.NewSet[int]()
	intSet.Add(1)
	intSet.Add(2)
	intSet.Add(3)
	fmt.Printf("Numbers: %d\n", intSet.Len())

	// Float set
	floatSet := wtype.NewSet[float64]()
	floatSet.Add(3.14)
	floatSet.Add(2.71)
	floatSet.Add(1.41)
	fmt.Printf("Constants: %d\n", floatSet.Len())

}
Output:

Programming languages: 3
Numbers: 3
Constants: 3

func NewSet added in v1.3.0

func NewSet[T comparable](val ...T) *Set[T]

NewSet creates a new empty Set.

Example

ExampleNewSet demonstrates creating a new set

package main

import (
	"fmt"

	"github.com/wuchieh/wtype"
)

func main() {
	// Create a new string set
	stringSet := wtype.NewSet[string]()
	fmt.Printf("New string set length: %d\n", stringSet.Len())

	// Create a new int set
	intSet := wtype.NewSet[int]()
	fmt.Printf("New int set length: %d\n", intSet.Len())

}
Output:

New string set length: 0
New int set length: 0

func (*Set[T]) Add added in v1.3.0

func (s *Set[T]) Add(data T)

Add adds an element to the set.

Example

ExampleSet_Add demonstrates adding elements to a set

package main

import (
	"fmt"

	"github.com/wuchieh/wtype"
)

func main() {
	set := wtype.NewSet[string]()

	// Add elements
	set.Add("apple")
	set.Add("banana")
	set.Add("cherry")

	fmt.Printf("Set length after adding 3 elements: %d\n", set.Len())

	// Adding duplicate element (no effect)
	set.Add("apple")
	fmt.Printf("Set length after adding duplicate: %d\n", set.Len())

}
Output:

Set length after adding 3 elements: 3
Set length after adding duplicate: 3

func (*Set[T]) Clear added in v1.3.0

func (s *Set[T]) Clear()

Clear removes all elements from the set.

Example

ExampleSet_Clear demonstrates clearing all elements from a set

package main

import (
	"fmt"

	"github.com/wuchieh/wtype"
)

func main() {
	set := wtype.NewSet[int]()
	set.Add(10)
	set.Add(20)
	set.Add(30)

	fmt.Printf("Before clear - Length: %d\n", set.Len())

	set.Clear()
	fmt.Printf("After clear - Length: %d\n", set.Len())
	fmt.Printf("Contains 10 after clear: %t\n", set.Contains(10))

}
Output:

Before clear - Length: 3
After clear - Length: 0
Contains 10 after clear: false

func (*Set[T]) Contains added in v1.3.0

func (s *Set[T]) Contains(data T) bool

Contains checks if an element exists in the set.

Example

ExampleSet_Contains demonstrates checking if elements exist in the set

package main

import (
	"fmt"

	"github.com/wuchieh/wtype"
)

func main() {
	set := wtype.NewSet[int]()
	set.Add(1)
	set.Add(2)
	set.Add(3)

	fmt.Printf("Contains 2: %t\n", set.Contains(2))
	fmt.Printf("Contains 5: %t\n", set.Contains(5))
	fmt.Printf("Contains 1: %t\n", set.Contains(1))

}
Output:

Contains 2: true
Contains 5: false
Contains 1: true

func (*Set[T]) Get added in v1.3.0

func (s *Set[T]) Get() []T

Get returns all elements in the set as a slice.

The order of elements is not guaranteed.
Example

ExampleSet_Get demonstrates getting all elements from a set

package main

import (
	"fmt"
	"sort"

	"github.com/wuchieh/wtype"
)

func main() {
	set := wtype.NewSet[int]()
	set.Add(3)
	set.Add(1)
	set.Add(4)
	set.Add(2)

	elements := set.Get()
	// Sort for consistent output since set order is not guaranteed
	sort.Ints(elements)
	fmt.Printf("Set elements: %v\n", elements)
	fmt.Printf("Number of elements: %d\n", len(elements))

}
Output:

Set elements: [1 2 3 4]
Number of elements: 4

func (*Set[T]) Len added in v1.3.0

func (s *Set[T]) Len() int

Len returns the number of elements in the set.

Example

ExampleSet_Len demonstrates getting the length of a set

package main

import (
	"fmt"

	"github.com/wuchieh/wtype"
)

func main() {
	set := wtype.NewSet[string]()

	fmt.Printf("Empty set length: %d\n", set.Len())

	set.Add("first")
	fmt.Printf("After adding 1 element: %d\n", set.Len())

	set.Add("second")
	set.Add("third")
	fmt.Printf("After adding 3 elements total: %d\n", set.Len())

}
Output:

Empty set length: 0
After adding 1 element: 1
After adding 3 elements total: 3

func (Set[T]) MarshalJSON added in v1.9.4

func (s Set[T]) MarshalJSON() ([]byte, error)

MarshalJSON implementation json.Marshal

func (*Set[T]) Range added in v1.3.0

func (s *Set[T]) Range(f func(T) bool)

Range iterates over the set and calls f for each element.

If f returns false, the iteration stops.
Example

ExampleSet_Range demonstrates iterating over set elements

package main

import (
	"fmt"

	"github.com/wuchieh/wtype"
)

func main() {
	set := wtype.NewSet[string]()
	set.Add("apple")
	set.Add("banana")
	set.Add("cherry")

	fmt.Println("All elements:")
	set.Range(func(element string) bool {
		fmt.Printf("- %s\n", element)
		return true // Continue iteration
	})

	fmt.Println("\nFirst 2 elements:")
	count := 0
	set.Range(func(element string) bool {
		fmt.Printf("- %s\n", element)
		count++
		return count < 2 // Stop after 2 elements
	})

	// Output will vary due to map iteration order, but structure will be:
	// All elements:
	// - apple
	// - banana
	// - cherry
	//
	// First 2 elements:
	// - apple
	// - banana
}
Example (ConditionalStop)

ExampleSet_Range_conditionalStop demonstrates stopping iteration early

package main

import (
	"fmt"

	"github.com/wuchieh/wtype"
)

func main() {
	set := wtype.NewSet[int]()
	for i := 1; i <= 10; i++ {
		set.Add(i)
	}

	fmt.Println("Numbers until we find one > 5:")
	set.Range(func(num int) bool {
		fmt.Printf("%d ", num)
		return num <= 5 // Stop when we find a number > 5
	})
	fmt.Println()

	// Output will vary due to map iteration order, but will stop early
}

func (*Set[T]) Remove added in v1.3.0

func (s *Set[T]) Remove(data T)

Remove removes an element from the set.

Example

ExampleSet_Remove demonstrates removing elements from a set

package main

import (
	"fmt"

	"github.com/wuchieh/wtype"
)

func main() {
	set := wtype.NewSet[string]()
	set.Add("red")
	set.Add("green")
	set.Add("blue")

	fmt.Printf("Before removal - Length: %d, Contains 'green': %t\n",
		set.Len(), set.Contains("green"))

	// Remove an existing element
	set.Remove("green")
	fmt.Printf("After removing 'green' - Length: %d, Contains 'green': %t\n",
		set.Len(), set.Contains("green"))

	// Remove a non-existing element (no effect)
	set.Remove("yellow")
	fmt.Printf("After removing non-existing 'yellow' - Length: %d\n", set.Len())

}
Output:

Before removal - Length: 3, Contains 'green': true
After removing 'green' - Length: 2, Contains 'green': false
After removing non-existing 'yellow' - Length: 2

func (*Set[T]) SortValues added in v1.9.4

func (s *Set[T]) SortValues(cmp func(a T, b T) bool) []T

SortValues sort the set values

func (*Set[T]) UnmarshalJSON added in v1.9.4

func (s *Set[T]) UnmarshalJSON(bytes []byte) error

UnmarshalJSON implementation json.Unmarshal

func (*Set[T]) Values added in v1.6.0

func (s *Set[T]) Values() []T

Values is an alias for Get.

type SharedChanResult added in v1.6.2

type SharedChanResult[T any] struct {
	singleflight.Result
	Val T
}

type SliceString added in v1.6.0

type SliceString []String

func NewSliceString added in v1.6.0

func NewSliceString[T string | String](s ...T) SliceString

func (*SliceString) Join added in v1.6.0

func (s *SliceString) Join(sep ...string) *String

func (*SliceString) ToString added in v1.6.0

func (s *SliceString) ToString() []string

type SqlJSON added in v1.7.0

type SqlJSON json.RawMessage

func (SqlJSON) GormDBDataType added in v1.7.0

func (SqlJSON) GormDBDataType(db *gorm.DB, _ *schema.Field) string

GormDBDataType implements migrator.GormDataTypeInterface interface

func (*SqlJSON) Scan added in v1.7.0

func (j *SqlJSON) Scan(value interface{}) error

Scan implements sql.Scanner interface

func (SqlJSON) Value added in v1.7.0

func (j SqlJSON) Value() (driver.Value, error)

Value implements driver.Valuer interface

type SqlJSON2 added in v1.8.0

type SqlJSON2[T any] struct {
	SqlJSON
}

func (*SqlJSON2[T]) Scan added in v1.8.0

func (j *SqlJSON2[T]) Scan(value interface{}) error

func (SqlJSON2[T]) Unmarshal added in v1.8.0

func (j SqlJSON2[T]) Unmarshal(a *T) error

type String added in v1.6.0

type String string

func NewString added in v1.6.0

func NewString[T ~string](s T) *String

func (*String) Contains added in v1.6.0

func (s *String) Contains(substr string) bool

func (*String) Count added in v1.9.4

func (s *String) Count(substr string) int

func (*String) HasPrefix added in v1.9.4

func (s *String) HasPrefix(prefix string) bool

func (*String) HasSuffix added in v1.9.4

func (s *String) HasSuffix(suffix string) bool

func (*String) Includes added in v1.6.0

func (s *String) Includes(substr string) bool

func (*String) Len added in v1.9.2

func (s *String) Len() int

func (*String) Repeat added in v1.6.0

func (s *String) Repeat(count int) *String

func (*String) Replace added in v1.6.0

func (s *String) Replace(old, new string, n int) *String

func (*String) ReplaceAll added in v1.6.0

func (s *String) ReplaceAll(old, new string) *String

func (*String) Slice added in v1.6.0

func (s *String) Slice(start int, end ...int) *String

func (*String) Split added in v1.6.0

func (s *String) Split(sep ...string) SliceString

func (*String) String added in v1.6.0

func (s *String) String() string

func (*String) ToLower added in v1.9.2

func (s *String) ToLower() *String

func (*String) ToString added in v1.6.0

func (s *String) ToString() string

func (*String) ToUpper added in v1.9.2

func (s *String) ToUpper() *String

func (*String) Trim added in v1.6.0

func (s *String) Trim() *String

type SyncMap added in v1.5.0

type SyncMap[K comparable, V any] struct {
	// contains filtered or unexported fields
}

func NewSyncMap added in v1.5.0

func NewSyncMap[K comparable, V any]() *SyncMap[K, V]
Example
package main

import (
	"encoding/json"
	"fmt"
	"log"

	"github.com/wuchieh/wtype"
)

func main() {
	m := wtype.NewSyncMap[string, int]()
	m.Store("a", 1)
	m.Store("b", 2)
	m.Range(func(key string, value int) bool {
		m.Store(key, value+1)
		return true
	})
	m.Range(func(key string, value int) bool {
		fmt.Println(key, value)
		return true
	})

	actual, loaded := m.LoadOrStore("a", 1)
	fmt.Println(actual, loaded)

	b, err := json.Marshal(m)
	if err != nil {
		log.Fatal("json.Marshal Error:", err)
	}

	var m2 wtype.SyncMap[string, int]
	err = json.Unmarshal(b, &m2)
	if err != nil {
		log.Fatal("json.Unmarshal Error:", err)
	}

	a, _ := m2.Load("a")
	fmt.Println(a == 2)

}
Output:

a 2
b 3
2 true
true

func (*SyncMap[K, V]) Clear added in v1.5.0

func (s *SyncMap[K, V]) Clear()

func (*SyncMap[K, V]) CompareAndDelete added in v1.5.0

func (s *SyncMap[K, V]) CompareAndDelete(key K, old V) (deleted bool)

func (*SyncMap[K, V]) CompareAndSwap added in v1.5.0

func (s *SyncMap[K, V]) CompareAndSwap(key K, old V, new V) (swapped bool)

func (*SyncMap[K, V]) Delete added in v1.5.0

func (s *SyncMap[K, V]) Delete(key K)

func (*SyncMap[K, V]) Load added in v1.5.0

func (s *SyncMap[K, V]) Load(key K) (value V, ok bool)

func (*SyncMap[K, V]) LoadAndDelete added in v1.5.0

func (s *SyncMap[K, V]) LoadAndDelete(key K) (value V, loaded bool)

func (*SyncMap[K, V]) LoadOrStore added in v1.5.0

func (s *SyncMap[K, V]) LoadOrStore(key K, value V) (actual V, loaded bool)

func (*SyncMap[K, V]) MarshalJSON added in v1.9.1

func (s *SyncMap[K, V]) MarshalJSON() ([]byte, error)

MarshalJSON implementation json.Marshal

func (*SyncMap[K, V]) Range added in v1.5.0

func (s *SyncMap[K, V]) Range(f func(key K, value V) (shouldContinue bool))

func (*SyncMap[K, V]) Store added in v1.5.0

func (s *SyncMap[K, V]) Store(key K, value V)

func (*SyncMap[K, V]) Swap added in v1.5.0

func (s *SyncMap[K, V]) Swap(key K, value V) (previous V, loaded bool)

func (*SyncMap[K, V]) UnmarshalJSON added in v1.9.4

func (s *SyncMap[K, V]) UnmarshalJSON(bytes []byte) error

UnmarshalJSON implementation json.Unmarshal

Jump to

Keyboard shortcuts

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