CUE 上下文(Context)



介绍 CUE 的 Go API 要从上下文对象 cue.Context 开始。 上下文对象可以用来编译 CUE 代码和构建 values 对象(稍后章节介绍)。 下面介绍上下文对象的基本用法,后面的章节会逐步增加复杂的场景。

当操作多个 value 的时候,他们应当来自同一个运行时。这个要求会在未来的版本中移除。

使用 Context 编译

这是一个最简单的程序,打印一个 CUE value 对象。 如果其中有错误,程序将会打印遇到的第一个错误。

context.go

package main

import (
	"fmt"

	"cuelang.org/go/cue"
	"cuelang.org/go/cue/cuecontext"
)

const val = `
i: int
s: "hello"
`

func main() {
	var (
		c *cue.Context
		v cue.Value
	)

	// create a context
	c = cuecontext.New()

	// compile some CUE into a Value
	v = c.CompileString(val)

	// print the value
	fmt.Println(v)
}

go run context.go

{
	i: int
	s: "hello"
}

编译时指定范围(Scope)

如果值(value)和类型(schema)在不同的字符串中, 你可以使用 cue.Scope 选项来给 cue.Context 对象提供一个更具体的上下文。

scope.go

package main

import (
	"fmt"

	"cuelang.org/go/cue"
	"cuelang.org/go/cue/cuecontext"
)

const schema = `
#schema: {
	i: int
	s: string
}
`

const val = `
v: #schema & {
	i: 1
	s: "hello"
}
`

func main() {
	var (
		c *cue.Context
		s cue.Value
		v cue.Value
	)

	// create a context
	c = cuecontext.New()

	// compile our schema first
	s = c.CompileString(schema)

	// compile our value with scope
	v = c.CompileString(val, cue.Scope(s))

	// print the value
	fmt.Println(v)
}

go run scope.go

{
	v: {
		i: 1
		s: "hello"
	}
}

从 Go 类型编码为 Value

你可以把你的 Go 类型和值转为 CUE value。 可以通过结构体标签(tag)来控制输出。注意

  • 只有导出的字段可以被CUE编码
  • 可以使用 omitempty 阻止输出该字段,但是这样也会影响这个类型的其他编码。
  • 数字类型有一些怪异之处,我们稍后再谈。CUE 通常使用 math/big 类型。
  • 你可以在这里查看细节 pkg.go.dev cue.Context.Encode docs.

encoding.go

package main

import (
	"fmt"

	"cuelang.org/go/cue"
	"cuelang.org/go/cue/cuecontext"
)

type Val struct {
	I int    `json:"i"`
	S string `json:"s,omitempty"`
	b bool
}

func main() {
	var (
		c *cue.Context
		v cue.Value
	)

	val := Val{
		I: 1,
		S: "hello",
		b: true,
	}

	// create a context
	c = cuecontext.New()

	// compile some CUE into a Value
	v = c.Encode(val)

	// print the value
	fmt.Println(v)

	// we can also encode types
	t := c.EncodeType(Val{})
	fmt.Println(t)
}

go run encoding.go

{
	i: 1
	s: "hello"
}
{
	i: int64
}
我们绝不会将你的邮箱分享给任何人。
2022 Hofstadter, Inc