future

package module
v0.1.5 Latest Latest
Warning

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

Go to latest
Published: Jun 24, 2025 License: Apache-2.0 Imports: 8 Imported by: 0

README

go-future

codecov goreport

go-future is a lightweight, high-performance, lock-free Future/Promise implementation for Go, built with modern concurrency in mind. It supports:

  • Asynchronous task execution (Async, CtxAsync)
  • Lazy evaluation (Lazy)(Deprecated, will be removed in later version)
  • Promise resolution (Promise)
  • Event-driven callback registration (Subscribe)
  • Functional chaining (Then, ThenAsync)
  • Task composition (AllOf, AnyOf)
  • Timeout control (Timeout, Until)
  • Full support for Go generics

🔧 Installation

go get github.com/jizhuozhi/go-future

🚀 Quick Start

package main

import (
	"fmt"
	"github.com/jizhuozhi/go-future"
)

func main() {
	p := future.NewPromise[string]()
	go func() {
		p.Set("hello", nil)
	}()
	val, err := p.Future().Get()
	fmt.Println(val, err) // Output: hello <nil>
}

🧠 Core Concepts

Promise and Future
  • Promise is the producer, which sets the value once.
  • Future is the consumer, which retrieves the result asynchronously.

Every Future is backed by a lock-free internal state. All state transitions are safe and efficient under high concurrency.


🔨 Key APIs

Async(func() (T, error)) *Future[T]

Starts a new asynchronous task in a goroutine.

f := future.Async(func() (string, error) {
	return "result", nil
})
val, err := f.Get()

Lazy(func() (T, error)) *Future[T]

Returns a future that is lazily evaluated. The function is only executed once on the first call to .Get().

f := future.Lazy(func() (string, error) {
	fmt.Println("evaluated")
	return "lazy", nil
})
val, _ := f.Get() // prints "evaluated"
⚠️ Deprecation Notice: Lazy

The Lazy API is deprecated and will be removed in future versions.

Although Lazy provides deferred execution semantics, it introduces implicit pull-based dependencies that are difficult to reason about in practice. Unlike Async, where execution is guaranteed upon construction, Lazy defers execution until .Get() is called — often far away from the site of definition.

This subtle semantic difference:

  • Makes control flow harder to predict
  • Breaks intuitive data dependency modeling
  • Can result in unexpected bugs when chained or composed in concurrent settings

Recommendation: Prefer using Async or Promise for all use cases. These are explicit and deterministic.


Promise[T]

Used to create and control a future manually.

p := future.NewPromise[int]()
go func() {
	p.Set(42, nil)
}()
val, _ := p.Future().Get()

Then(f *Future[T], cb func(T, error) (R, error)) *Future[R]

Chains computations synchronously.

f := future.Async(func() (int, error) { return 1, nil })
f2 := future.Then(f, func(v int, err error) (string, error) {
	return fmt.Sprintf("num:%d", v), err
})
result, _ := f2.Get()

ThenAsync(f *Future[T], cb func(T, error) *Future[R]) *Future[R]

Chains computations with asynchronous return.

f := future.Async(func() (int, error) { return 1, nil })
f2 := future.ThenAsync(f, func(v int, err error) *future.Future[string] {
	return future.Async(func() (string, error) {
		return fmt.Sprintf("async:%d", v), nil
	})
})
result, _ := f2.Get()

AllOf(fs ...*Future[T]) *Future[[]T]

Waits for all futures to complete successfully. Fails fast on the first error.

f1 := future.Async(func() (int, error) { return 1, nil })
f2 := future.Async(func() (int, error) { return 2, nil })
fAll := future.AllOf(f1, f2)
vals, _ := fAll.Get() // [1, 2]

AnyOf(fs ...*Future[T]) *Future[AnyResult[T]]

Returns the first successful result. If all fail, returns the first error.

f1 := future.Async(func() (int, error) { return 0, fmt.Errorf("fail") })
f2 := future.Async(func() (int, error) { return 2, nil })
res, _ := future.AnyOf(f1, f2).Get()
// res.Index == 1, res.Val == 2

Timeout(f *Future[T], d time.Duration) *Future[T]

Wraps a future and fails with ErrTimeout if not resolved in time.

f := future.Async(func() (int, error) {
	time.Sleep(2 * time.Second)
	return 42, nil
})
val, err := future.Timeout(f, time.Second).Get()
// err == future.ErrTimeout

Done(val T) *Future[T], Done2(val T, err error)

Create a completed Future.

f := future.Done("value")
f2 := future.Done2("value", nil)

Subscribe(cb func(T, error))

Registers a callback that runs when the Future is done.

f := future.Async(func() (int, error) { return 1, nil })
f.Subscribe(func(v int, err error) {
	fmt.Println("got:", v)
})

⚠️ Callbacks execute in the same goroutine that completes the Future. Avoid blocking operations in the callback.


✅ Advantages

  • Zero Locking: Internals are implemented using atomic state machines, not sync.Mutex.
  • Type Safe: Full support for Go generics.
  • No Goroutine Bloat: Except Async, all operations are event-driven, avoiding extra goroutines.
  • Composable: Easily chainable, supports DAG-like workflows.

📊 Benchmark

goos: darwin
goarch: arm64
pkg: github.com/jizhuozhi/go-future
Benchmark/Promise           3.05M	    377 ns/op
Benchmark/WaitGroup         2.88M	    424 ns/op
Benchmark/Channel           3.00M	    399 ns/op

Promise is competitive with sync.WaitGroup and channel in terms of performance and offers much better composition semantics.


📦 DAG Execution Engine (Experimental)

Starting from v0.1.4, go-future introduces a powerful DAG (Directed Acyclic Graph) execution engine, consisting of:

  • dagcore: A minimal, lock-free parallel DAG scheduler
  • dagfunc: A high-level builder that constructs DAGs using Go function signatures with type-based dependency resolution

This enables users to describe complex data flow graphs declaratively with automatic dependency wiring and parallel execution.

dagcore

dagcore is the low-level DAG execution engine powering go-future's structured concurrency and dataflow execution model. It provides a lock-free, dependency-driven scheduler for executing static DAGs (Directed Acyclic Graphs) in parallel.

✨ Features
  • Lock-free execution via atomic dependency counters
  • ⛓️ Supports any static DAG with arbitrary fan-in/out structure
  • 🔁 Exactly-once execution: each node runs exactly once after its dependencies complete
  • 🧠 On-demand scheduling: nodes are only triggered once all dependencies complete — goroutines are created only when the node is ready to run
  • Fast failure support: optional early cancellation on error (fail-fast mode)
  • ⏱️ Context propagation: full support for timeout and cancellation via context.Context
  • 🧩 Composable foundation: designed for embedding in higher-level DAG builders (e.g. dagfunc)
  • 📈 Metrics & logging hooks: supports per-node wrappers for observability (e.g. retry, timing, logging)

🚀 Example Usage
dag := dagcore.NewDAG()

// Define DAG structure
_ = dag.AddInput("A")
_ = dag.AddNode("B", []dagcore.NodeID{"A"}, func(ctx context.Context, deps map[dagcore.NodeID]any) (any, error) {
    return deps["A"].(int) + 2, nil
})
_ = dag.AddNode("C", []dagcore.NodeID{"A"}, func(ctx context.Context, deps map[dagcore.NodeID]any) (any, error) {
    return deps["A"].(int) * 3, nil
})

// Execute
inst, _ := dag.Instantiate(map[dagcore.NodeID]any{"A": 10})
res, _ := inst.Execute(context.Background())
fmt.Println("B:", res["B"], "C:", res["C"])

🧠 Execution Model

Each node in the DAG:

  • Declares its dependencies via AddNode(id, deps, func)
  • Executes only once after all its inputs are ready
  • Will not allocate any goroutine until scheduled — on-demand execution
  • May run in parallel with other ready nodes
  • Propagates failures down dependent nodes (fail-fast)

Internally:

  • Uses atomic counters to track pending dependencies per node
  • Uses future.Future to propagate results, cancellation, and errors
  • Can be fully composed and integrated with the rest of go-future

⚙️ API Overview
dagcore.NewDAG() *DAG

Creates a new empty DAG instance.

(*DAG).AddInput(id NodeID) error

Adds a node that must be externally provided during execution.

(*DAG).AddNode(id NodeID, deps []NodeID, fn NodeFunc) error

Adds a computational node with declared dependencies.

(*DAG).Instantiate(inputs map[NodeID]any, wrappers ...NodeFuncWrapper) (*DAGInstance, error)

Creates a runtime instance of the DAG for execution.

(*DAGInstance).Run(ctx context.Context) (map[NodeID]any, error)

Executes all nodes and returns the final results.

(*DAGInstance).RunAsync(ctx context.Context) *Future[map[NodeID]any]

Runs asynchronously and returns a future.


🔧 Advanced Features
NodeFunc Wrapping

Use NodeFuncWrapper to wrap node logic for tracing, logging, retries, etc:

dag.Instantiate(inputs, func(n *dagcore.NodeInstance, fn dagcore.NodeFunc) dagcore.NodeFunc {
    return func(ctx context.Context, deps map[dagcore.NodeID]any) (any, error) {
        start := time.Now()
        out, err := fn(ctx, deps)
        log.Printf("node %s took %s", n.ID(), time.Since(start))
        return out, err
    }
})
Mermaid Graph Output

Convert the DAG to a Mermaid.js compatible graph string:

fmt.Println(dagcore.ToMermaid(instance))

🧱 Designed for Composition

dagcore is intended to be embedded in high-level tools:

  • dagfunc: type-safe DAG builder with Go function signature inference
  • Custom domain-specific orchestrators, AI pipelines, CI/CD workflows
  • Any static dependency graph evaluation with result propagation

dagfunc

dagfunc is a high-level, type-safe DAG (Directed Acyclic Graph) builder built on top of dagcore. It allows you to define and execute dependency graphs by simply wiring Go functions based on their parameter and return types.

🚀 What It Solves

dagfunc abstracts away manual DAG construction by:

  • Automatically inferring node dependencies from function signatures
  • Resolving dependency order at compile-time
  • Mapping types to results without needing manual wiring

Ideal for:

  • AI agent pipelines
  • Asynchronous service orchestration
  • Task graph composition with clear dependency semantics

✅ Features
  • ✅ Type-based dependency inference
  • ✅ Fully integrated with go-future for parallel execution
  • ✅ Reusable functions with Go-style declarations
  • ✅ Built-in support for context propagation and error handling
  • ✅ Alias support to distinguish same-type dependencies

🔧 Installation
go get github.com/jizhuozhi/go-future/dagfunc

✨ Example
package main

import (
	"context"
	"fmt"
	"github.com/jizhuozhi/go-future/dagfunc"
)

func main() {
	type Input string
	type TokenCount int

	b := dagfunc.New()

	// Step 1: Declare input
	_ = b.Provide(Input(""))

	// Step 2: Register function
	_ = b.Use(func(ctx context.Context, text Input) (TokenCount, error) {
		return TokenCount(len(text)), nil
	})

	// Step 3: Run
	prog, _ := b.Compile([]any{Input("hello world")})
	out, _ := prog.Run(context.Background())
	fmt.Println(out[TokenCount(0)]) // Output: 11
}

🧠 Type-Based Wiring

dagfunc determines node dependencies using parameter types and result types:

  • Each function must accept context.Context as the first argument
  • Inputs and outputs must use unique Go types or aliases
  • The DAG will automatically determine execution order

⚠️ If two inputs/outputs are of the same type (e.g., multiple string values), use type alias to disambiguate.

With type alias
type UserID string
type Greeting string

b.Provide(UserID(""))
b.Use(func(ctx context.Context, uid UserID) (Greeting, error) {
	return Greeting("Hello, " + string(uid)), nil
})
b.Use(func(ctx context.Context, g Greeting) (string, error) {
	return string(g), nil
})

🧰 API Overview
dagfunc.New() *Builder

Creates a new DAG builder.

(*Builder).Provide(val any) error

Declares a root node with known value.

(*Builder).Use(fn any) error

Registers a function as a DAG node. Must match:

func(ctx context.Context, A, B, ...) (X, Y, ..., error)
(*Builder).Compile(inputs []any) (*Program, error)

Builds a DAG using the provided inputs.

(*Program).Run(ctx context.Context) (map[any]any, error)

Executes the DAG. Outputs are keyed by result types with typed zero.

(*Program).RunAsync(ctx context.Context) *future.Future[map[any]any]

Executes the DAG. Return a future with outputs are keyed by result types with typed zero.

(*Program).Get(any) (any, error)

Gets the result value for a specific type.

Error propagation
  • DAG execution will fail fast by default
  • Downstream nodes will not be executed if inputs fail
  • You can customize error behavior using dagcore

🧩 Relationship to dagcore
Layer Role
dagfunc High-level: Build DAGs from Go functions
dagcore Low-level: Execute DAGs with scheduling
go-future Runtime: Power async execution via Future

💡 Use Cases
  • LLM / Agent planning pipelines
  • Microservice DAG invocation
  • Declarative orchestration of business logic
  • Build systems / task runners

📌 Notes
  • Outputs are retrieved by Go types (typed zero), not labels
  • Type aliasing is required for disambiguation
  • All dependencies must be resolvable at compile-time

🔐 License

Apache-2.0 license by jizhuozhi

Documentation

Index

Constants

This section is empty.

Variables

View Source
var ErrPanic = errors.New("async panic")
View Source
var ErrTimeout = errors.New("future timeout")

Functions

func Await

func Await[T any](f *Future[T]) (T, error)

func SetExecutor added in v0.1.5

func SetExecutor(e Executor)

Types

type AnyResult

type AnyResult[T any] struct {
	Index int
	Val   T
	Err   error
}

type Executor added in v0.1.5

type Executor interface {
	Submit(func())
}

type Future

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

Future The Future provides a mechanism to access the result of asynchronous operations:

1. An asynchronous operation (Async, Lazy or Promise) can provide a Future to the creator of that asynchronous operation.

2. The creator of the asynchronous operation can then use a variety of methods to query, wait for, or extract a value from the Future. These methods may block if the asynchronous operation has not yet provided a value.

3. When the asynchronous operation is ready to send a result to the creator, it can do so by modifying shared state (e.g. Promise.Set) that is linked to the creator's std::future.

The Future also has the ability to register a callback to be called when the asynchronous operation is ready to send a result to the creator.

func AllOf

func AllOf[T any](fs ...*Future[T]) *Future[[]T]

func AnyOf

func AnyOf[T any](fs ...*Future[T]) *Future[AnyResult[T]]

func Async

func Async[T any](f func() (T, error)) *Future[T]

func CtxAsync added in v0.1.4

func CtxAsync[T any](ctx context.Context, f func(ctx context.Context) (T, error)) *Future[T]

func CtxSubmit added in v0.1.5

func CtxSubmit[T any](ctx context.Context, e Executor, f func(ctx context.Context) (T, error)) *Future[T]

func Done

func Done[T any](val T) *Future[T]

func Done2 added in v0.1.3

func Done2[T any](val T, err error) *Future[T]

func Lazy

func Lazy[T any](f func() (T, error)) *Future[T]

Lazy Deprecated, will be removed in later version

func Of10 added in v0.1.4

func Of10[T0, T1, T2, T3, T4, T5, T6, T7, T8, T9 any](t0 *Future[T0], t1 *Future[T1], t2 *Future[T2], t3 *Future[T3], t4 *Future[T4], t5 *Future[T5], t6 *Future[T6], t7 *Future[T7], t8 *Future[T8], t9 *Future[T9]) *Future[Tuple10[T0, T1, T2, T3, T4, T5, T6, T7, T8, T9]]

func Of11 added in v0.1.4

func Of11[T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 any](t0 *Future[T0], t1 *Future[T1], t2 *Future[T2], t3 *Future[T3], t4 *Future[T4], t5 *Future[T5], t6 *Future[T6], t7 *Future[T7], t8 *Future[T8], t9 *Future[T9], t10 *Future[T10]) *Future[Tuple11[T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]]

func Of12 added in v0.1.4

func Of12[T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11 any](t0 *Future[T0], t1 *Future[T1], t2 *Future[T2], t3 *Future[T3], t4 *Future[T4], t5 *Future[T5], t6 *Future[T6], t7 *Future[T7], t8 *Future[T8], t9 *Future[T9], t10 *Future[T10], t11 *Future[T11]) *Future[Tuple12[T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11]]

func Of13 added in v0.1.4

func Of13[T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12 any](t0 *Future[T0], t1 *Future[T1], t2 *Future[T2], t3 *Future[T3], t4 *Future[T4], t5 *Future[T5], t6 *Future[T6], t7 *Future[T7], t8 *Future[T8], t9 *Future[T9], t10 *Future[T10], t11 *Future[T11], t12 *Future[T12]) *Future[Tuple13[T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12]]

func Of14 added in v0.1.4

func Of14[T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13 any](t0 *Future[T0], t1 *Future[T1], t2 *Future[T2], t3 *Future[T3], t4 *Future[T4], t5 *Future[T5], t6 *Future[T6], t7 *Future[T7], t8 *Future[T8], t9 *Future[T9], t10 *Future[T10], t11 *Future[T11], t12 *Future[T12], t13 *Future[T13]) *Future[Tuple14[T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13]]

func Of15 added in v0.1.4

func Of15[T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 any](t0 *Future[T0], t1 *Future[T1], t2 *Future[T2], t3 *Future[T3], t4 *Future[T4], t5 *Future[T5], t6 *Future[T6], t7 *Future[T7], t8 *Future[T8], t9 *Future[T9], t10 *Future[T10], t11 *Future[T11], t12 *Future[T12], t13 *Future[T13], t14 *Future[T14]) *Future[Tuple15[T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14]]

func Of16 added in v0.1.4

func Of16[T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15 any](t0 *Future[T0], t1 *Future[T1], t2 *Future[T2], t3 *Future[T3], t4 *Future[T4], t5 *Future[T5], t6 *Future[T6], t7 *Future[T7], t8 *Future[T8], t9 *Future[T9], t10 *Future[T10], t11 *Future[T11], t12 *Future[T12], t13 *Future[T13], t14 *Future[T14], t15 *Future[T15]) *Future[Tuple16[T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15]]

func Of2 added in v0.1.4

func Of2[T0, T1 any](t0 *Future[T0], t1 *Future[T1]) *Future[Tuple2[T0, T1]]

func Of3 added in v0.1.4

func Of3[T0, T1, T2 any](t0 *Future[T0], t1 *Future[T1], t2 *Future[T2]) *Future[Tuple3[T0, T1, T2]]

func Of4 added in v0.1.4

func Of4[T0, T1, T2, T3 any](t0 *Future[T0], t1 *Future[T1], t2 *Future[T2], t3 *Future[T3]) *Future[Tuple4[T0, T1, T2, T3]]

func Of5 added in v0.1.4

func Of5[T0, T1, T2, T3, T4 any](t0 *Future[T0], t1 *Future[T1], t2 *Future[T2], t3 *Future[T3], t4 *Future[T4]) *Future[Tuple5[T0, T1, T2, T3, T4]]

func Of6 added in v0.1.4

func Of6[T0, T1, T2, T3, T4, T5 any](t0 *Future[T0], t1 *Future[T1], t2 *Future[T2], t3 *Future[T3], t4 *Future[T4], t5 *Future[T5]) *Future[Tuple6[T0, T1, T2, T3, T4, T5]]

func Of7 added in v0.1.4

func Of7[T0, T1, T2, T3, T4, T5, T6 any](t0 *Future[T0], t1 *Future[T1], t2 *Future[T2], t3 *Future[T3], t4 *Future[T4], t5 *Future[T5], t6 *Future[T6]) *Future[Tuple7[T0, T1, T2, T3, T4, T5, T6]]

func Of8 added in v0.1.4

func Of8[T0, T1, T2, T3, T4, T5, T6, T7 any](t0 *Future[T0], t1 *Future[T1], t2 *Future[T2], t3 *Future[T3], t4 *Future[T4], t5 *Future[T5], t6 *Future[T6], t7 *Future[T7]) *Future[Tuple8[T0, T1, T2, T3, T4, T5, T6, T7]]

func Of9 added in v0.1.4

func Of9[T0, T1, T2, T3, T4, T5, T6, T7, T8 any](t0 *Future[T0], t1 *Future[T1], t2 *Future[T2], t3 *Future[T3], t4 *Future[T4], t5 *Future[T5], t6 *Future[T6], t7 *Future[T7], t8 *Future[T8]) *Future[Tuple9[T0, T1, T2, T3, T4, T5, T6, T7, T8]]

func Submit added in v0.1.5

func Submit[T any](e Executor, f func() (T, error)) *Future[T]

func Then

func Then[T any, R any](f *Future[T], cb func(T, error) (R, error)) *Future[R]

func ThenAsync

func ThenAsync[T any, R any](f *Future[T], cb func(T, error) *Future[R]) *Future[R]

func Timeout

func Timeout[T any](f *Future[T], d time.Duration) *Future[T]

func ToAny added in v0.1.1

func ToAny[T any](f *Future[T]) *Future[any]

func Until

func Until[T any](f *Future[T], t time.Time) *Future[T]

func (*Future[T]) Done added in v0.1.2

func (f *Future[T]) Done() bool

Done returns true if the Future is done.

func (*Future[T]) Get

func (f *Future[T]) Get() (T, error)

Get returns the value and error of the Future.

func (*Future[T]) GetOrDefault added in v0.1.2

func (f *Future[T]) GetOrDefault(defaultVal T) T

GetOrDefault returns the value of the Future. If error has been set, it returns the default value.

func (*Future[T]) Subscribe added in v0.1.2

func (f *Future[T]) Subscribe(cb func(val T, err error))

Subscribe registers a callback to be called when the Future is done.

NOTE: The callback will be called in goroutine that is the same as the goroutine which changed Future state. The callback should not contain any blocking operations.

type Promise

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

Promise The Promise provides a facility to store a value or an error that is later acquired asynchronously via a Future created by the Promise. Note that the Promise object is meant to be set only once.

Each Promise is associated with a shared state, which contains some state information and a result which may be not yet evaluated, evaluated to a value (possibly nil) or evaluated to an error.

The Promise is the "push" end of the promise-future communication channel: the operation that stores a value in the shared state synchronizes-with (as defined in Go's memory model) the successful return from any function that is waiting on the shared state (such as Future.Get).

A Promise must not be copied after first use.

func NewPromise

func NewPromise[T any]() *Promise[T]

NewPromise creates a new Promise object.

func (*Promise[T]) Free added in v0.1.2

func (p *Promise[T]) Free() bool

Free returns true if the Promise is not set.

func (*Promise[T]) Future

func (p *Promise[T]) Future() *Future[T]

Future returns a Future object associated with the Promise.

func (*Promise[T]) Set

func (p *Promise[T]) Set(val T, err error)

Set sets the value and error of the Promise.

func (*Promise[T]) SetSafety added in v0.1.3

func (p *Promise[T]) SetSafety(val T, err error) bool

SetSafety sets the value and error of the Promise, and it will return false if already set.

type Tuple10 added in v0.1.3

type Tuple10[T0, T1, T2, T3, T4, T5, T6, T7, T8, T9 any] struct {
	Val0 T0
	Val1 T1
	Val2 T2
	Val3 T3
	Val4 T4
	Val5 T5
	Val6 T6
	Val7 T7
	Val8 T8
	Val9 T9
}

type Tuple11 added in v0.1.3

type Tuple11[T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 any] struct {
	Val0  T0
	Val1  T1
	Val2  T2
	Val3  T3
	Val4  T4
	Val5  T5
	Val6  T6
	Val7  T7
	Val8  T8
	Val9  T9
	Val10 T10
}

type Tuple12 added in v0.1.3

type Tuple12[T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11 any] struct {
	Val0  T0
	Val1  T1
	Val2  T2
	Val3  T3
	Val4  T4
	Val5  T5
	Val6  T6
	Val7  T7
	Val8  T8
	Val9  T9
	Val10 T10
	Val11 T11
}

type Tuple13 added in v0.1.3

type Tuple13[T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12 any] struct {
	Val0  T0
	Val1  T1
	Val2  T2
	Val3  T3
	Val4  T4
	Val5  T5
	Val6  T6
	Val7  T7
	Val8  T8
	Val9  T9
	Val10 T10
	Val11 T11
	Val12 T12
}

type Tuple14 added in v0.1.3

type Tuple14[T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13 any] struct {
	Val0  T0
	Val1  T1
	Val2  T2
	Val3  T3
	Val4  T4
	Val5  T5
	Val6  T6
	Val7  T7
	Val8  T8
	Val9  T9
	Val10 T10
	Val11 T11
	Val12 T12
	Val13 T13
}

type Tuple15 added in v0.1.3

type Tuple15[T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 any] struct {
	Val0  T0
	Val1  T1
	Val2  T2
	Val3  T3
	Val4  T4
	Val5  T5
	Val6  T6
	Val7  T7
	Val8  T8
	Val9  T9
	Val10 T10
	Val11 T11
	Val12 T12
	Val13 T13
	Val14 T14
}

type Tuple16 added in v0.1.3

type Tuple16[T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15 any] struct {
	Val0  T0
	Val1  T1
	Val2  T2
	Val3  T3
	Val4  T4
	Val5  T5
	Val6  T6
	Val7  T7
	Val8  T8
	Val9  T9
	Val10 T10
	Val11 T11
	Val12 T12
	Val13 T13
	Val14 T14
	Val15 T15
}

type Tuple2 added in v0.1.3

type Tuple2[T0, T1 any] struct {
	Val0 T0
	Val1 T1
}

type Tuple3 added in v0.1.3

type Tuple3[T0, T1, T2 any] struct {
	Val0 T0
	Val1 T1
	Val2 T2
}

type Tuple4 added in v0.1.3

type Tuple4[T0, T1, T2, T3 any] struct {
	Val0 T0
	Val1 T1
	Val2 T2
	Val3 T3
}

type Tuple5 added in v0.1.3

type Tuple5[T0, T1, T2, T3, T4 any] struct {
	Val0 T0
	Val1 T1
	Val2 T2
	Val3 T3
	Val4 T4
}

type Tuple6 added in v0.1.3

type Tuple6[T0, T1, T2, T3, T4, T5 any] struct {
	Val0 T0
	Val1 T1
	Val2 T2
	Val3 T3
	Val4 T4
	Val5 T5
}

type Tuple7 added in v0.1.3

type Tuple7[T0, T1, T2, T3, T4, T5, T6 any] struct {
	Val0 T0
	Val1 T1
	Val2 T2
	Val3 T3
	Val4 T4
	Val5 T5
	Val6 T6
}

type Tuple8 added in v0.1.3

type Tuple8[T0, T1, T2, T3, T4, T5, T6, T7 any] struct {
	Val0 T0
	Val1 T1
	Val2 T2
	Val3 T3
	Val4 T4
	Val5 T5
	Val6 T6
	Val7 T7
}

type Tuple9 added in v0.1.3

type Tuple9[T0, T1, T2, T3, T4, T5, T6, T7, T8 any] struct {
	Val0 T0
	Val1 T1
	Val2 T2
	Val3 T3
	Val4 T4
	Val5 T5
	Val6 T6
	Val7 T7
	Val8 T8
}

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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