ruk·si

Go
Lazy Evaluation

Updated at 2015-08-31 23:34

sync package offers Once which allow creating lazy evaluation out of the box.

package main

import (
    "fmt"
    "sync"
    "time"
)

func assert(condition bool) {
    if !condition {
        panic("assert failed")
    }
}

type LazyExpensive struct {
    once   sync.Once
    values []int
}

func (le *LazyExpensive) init() {
    le.values = []int{1, 2, 3, 4, 5}
    fmt.Println("a very expensive operation!")
}

func (le *LazyExpensive) Values() []int {
    le.once.Do(le.init)
    return le.values
}

func main() {
    // `init` will be called only once, and only after the first `Values` call
    le := LazyExpensive{}
    time.Sleep(1 * time.Second)
    fmt.Println(le.Values())
    time.Sleep(1 * time.Second)
    fmt.Println(le.Values())
    time.Sleep(1 * time.Second)
    fmt.Println(le.Values())
}

Sources