golang template(数组循环、在循环内使用外部变量、索引从1开始)

template之前也使用过,但都是一些最简单的字符串替换,但是从来没有使用过数组的循环遍历.

官方文档在这:https://golang.org/pkg/text/template/ 。 看的云里雾里的

 

之前做prometheus监控告警的时候为了适配各种类型的告警,把告警表达式模板抽出来了。

avg by(instance,prometheus_replica) (rate(node_cpu_seconds_total{mode = 'system', instance =~ '^{{.host}}.*'}[5m])) * 100

 代码简单,expression是PromQL表达式模板,使用{{}}作为定界符,queryMap的key是具体要替换的字符串,比如host,queryMap的value是具体的值,比如10.10.13.2。

func GetQueryPromQlExpr(name, expression string, queryMap map[string]interface{}) string {
	tpl := template.Must(template.New(name+"-expr").Delims("{{", "}}").Parse(expression))
	var buf bytes.Buffer
	err := tpl.Execute(&buf, queryMap)
	if err != nil {
		klog.Errorf("parse query:%s expression err:%s", name, err.Error())
		return ""
	}
	return buf.String()
}

 

现在有个需求是给了我一个文件模板,模板里面的内容是动态的,尤其是模板里面还会涉及到数组的使用。

理想效果是这样的:

[masters]
master1.okd.local  10.10.11.1
master2.okd.local  10.10.11.2
master3.okd.local  10.10.11.3
[nodes]
node1.okd.local  10.10.12.1
node2.okd.local  10.10.12.2
node3.okd.local  10.10.12.3

但是前端给到我的是一个master ip的数组,[masters]模块里面的内容具体有多少行,取决于前端传入的master ip数组的大小。

当前给我的数组长度为3,那么就会有3行,同理如果数组长度为10,那么就会生成10行记录。

master后面的数字相当于是数组的索引(从1开始的),在每一行末尾还有一个ip地址。

定义结构体

type Manifest struct {
	ClusterDomain string
	MasterIps     []string
    NodeIps       []string
}

结构体里面的字段首字母要大写,否则一会儿运行模板的时候无法解析到。 

定义字符串模板

ClusterDomain是公共的,要在range里面使用,需要使用$.Var

参考:https://studygolang.com/articles/3071

var manifestTpl = `
[masters]
{{range $index, $value := .MasterIps}}
   master{{$index}}.{{$.ClusterDomain}} {{$value}}
{{end}}
[nodes]
{{range $index, $value := .NodeIps}} 
   master{{$index}}.{{$.ClusterDomain}} {{$value}}
{{end}}
`

循环模板,以及在循环内使用外部变量

func TestTmpl(t *testing.T) {
	manifest := Manifest{
		ClusterDomain: "okd.local",
		MasterIps:     []string{"10.10.13.2", "10.10.13.3"},
		NodeIps:       []string{"10.10.14.2", "10.10.14.3"},
	}
	manifestTpl, err := template.New("manifest").Parse(manifestTpl)
	assert.Equal(t, nil, err)
	var buf bytes.Buffer
	assert.Equal(t, nil, manifestTpl.Execute(&buf, manifest))
	fmt.Println(buf.String())
}

目前这个代码执行出来的结果是下标从0开始。

下标从1开始

如果要让下标从0开始,可以自定义一个inc函数。

 funcMap := template.FuncMap{
        // The name "inc" is what the function will be called in the template text.
        "inc": func(i int) int {
            return i + 1
        },
    }

现在只要模板里面的index都调用inc参数即可实现在原有index基础上加1的效果。

新的模板

var manifestTpl = `
[masters]
{{range $index, $value := .MasterIps}}
   master{{inc $index}}.{{$.ClusterDomain}} {{$value}}
{{end}}
[nodes]
{{range $index, $value := .NodeIps}} 
   master{{inc $index}}.{{$.ClusterDomain}} {{$value}}
{{end}}
`

新的代码

func TestTmpl(t *testing.T) {
	manifest := Manifest{
		ClusterDomain: "okd.local",
		MasterIps:     []string{"10.10.13.2", "10.10.13.3"},
		NodeIps:       []string{"10.10.14.2", "10.10.14.3"},
	}
	funcMap := template.FuncMap{
		// The name "inc" is what the function will be called in the template text.
		"inc": func(i int) int {
			return i + 1
		},
	}
	manifestTpl, err := template.New("manifest").Funcs(funcMap).Parse(manifestTpl)
	assert.Equal(t, nil, err)
	var buf bytes.Buffer
	assert.Equal(t, nil, manifestTpl.Execute(&buf, manifest))
	fmt.Println(buf.String())
}

 

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值