Skip to main content
Version: v1.16

Environment

The environment is a map or a struct that contains the variables and functions that the expression can access.

Struct as Environment

Let's consider the following example:

type Env struct {
UpdatedAt time.Time
Posts []Post
Map map[string]string `expr:"tags"`
}

The Env struct contains 3 variables that the expression can access: UpdatedAt, Posts, and tags.

info

The expr tag is used to rename the Map field to tags variable in the expression.

The Env struct can also contain methods. The methods defined on the struct become functions that the expression can call.

func (Env) Format(t time.Time) string {
return t.Format(time.RFC822)
}
tip

Methods defined on embedded structs are also accessible.

type Env struct {
Helpers
}

type Helpers struct{}

func (Helpers) Format(t time.Time) string {
return t.Format(time.RFC822)
}

We can use an empty struct Env{} to with expr.Env to create an environment. Expr will use reflection to find the fields and methods of the struct.

program, err := expr.Compile(code, expr.Env(Env{}))

Compiler will type check the expression against the environment. After the compilation, we can run the program with the environment. You should use the same type of environment that you passed to the expr.Env function.

output, err := expr.Run(program, Env{
UpdatedAt: time.Now(),
Posts: []Post{{Title: "Hello, World!"}},
Map: map[string]string{"tag1": "value1"},
})

Map as Environment

You can also use a map as an environment.

env := map[string]any{
"UpdatedAt": time.Time{},
"Posts": []Post{},
"tags": map[string]string{},
"sprintf": fmt.Sprintf,
}

program, err := expr.Compile(code, expr.Env(env))

A map defines variables and functions that the expression can access. The key is the variable name, and the type is the value's type.

env := map[string]any{
"object": map[string]any{
"field": 42,
},
"struct": struct {
Field int `expr:"field"`
}{42},
}

Expr will infer the type of the object variable as map[string]any. Accessing fields of the object and struct variables will return the following results.

object.field   // 42
object.unknown // nil (no error)

struct.field // 42
struct.unknown // error (unknown field)

foobar // error (unknown variable)
note

The foobar variable is not defined in the environment. By default, Expr will return an error if unknown variables are used in the expression. You can disable this behavior by passing AllowUndefinedVariables option to the compiler.