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())
template之前也使用过,但都是一些最简单的字符串替换,但是从来没有使用过数组的循环遍历.官方文档在这:https://golang.org/pkg/text/template/。 看的云里雾里的之前做prometheus监控告警的时候为了适配各种类型的告警,把告警表达式模板抽出来了。avg by(instance,prometheus_replica) (rate(node_cpu_seconds_total{mode = 'system', instance =~ '^{{.h..
前言:最近做的tasks基本上都是与golang的template有关,今天有时间,对go的template的基本也是常用的语法规则做一个小小的总结。把自己踩到的坑列出来
模板:何为template呢?golang里面的template不要认为和go的语法有什么关系,如果你那样觉得,那你就是too young too simple;template与go的语法其实一点关系也没有,甚至是完全不同的
go get github.com/pravj/cqueue
一个循环缓冲区结构
// CQueue represents a circular buffer data structure
type CQueue struct {
// size limit of the buffer
size int
// occupied size of the buffer
Length int
// list containing all the buffer elements
Queue * list. List
// element at the front-side of the buffer
Head * list. Element
// element at the back-
golang(中文名:go语言)是谷歌2009发布的第二款开源编程语言。Go语言专门针对多处理器系统应用程序的编程进行了优化,使用Go编译的程序可以媲美C或C++代码的速度,而且更加安全、支持并行进程。。如果你想知道得更多,请移步至官网golang官网
在 Go 中函数的调用是值拷贝 copy value,而且在 for 循环中 v 的变量始终是一个变量。如果 v 是 pointer,print 这个 method 接收的是指针的拷贝,for 循环体中每次迭代 v 的 pointer value 都是不同的,所以输出不同。
在 Go 常见的错误一文中 http://devs.cloudi
文章目录1. 使用 map 的简单示例2. 循环2.1 `{{range $i, $e := pipeline }}2.2 {{range .pipeline}}引用外部变量
1. 使用 map 的简单示例
package main
import (
"fmt"
"text/template"
"bytes"
func main() {
tplStr := `my name is ...
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Go Web</title>
</head>
{{ range . }}
<li>{{ . }}</li>
{{ else }}
一:首先贴代码(你们大概看看就行,在看看后面的数据 你们就能理解 结构体嵌套的案例)
如果是PHP就方便很多,直接
数组嵌套
数组就行,也就是二维
数组。
package model
import (
type Find struct {
Article []Article
SelectArticle []SelectArticle
RecoArticle []SelectArticle
SelectLabel []SelectLabel
IndexAbout SiteInfo
IndexContact SiteInfo
go template 循环中使用 外部变量
range…end结构内部如要使用外部的变量,比如.Var,需要这样写:$.Var
(即:在外部变量名称前加符号“”即可,单独的“”即可,单独的“”即可,单独的“”意义等同于global)
npm i art-template
2.引入模板
<script src="./node_modules/art-template/lib/template-web.js"></script>
注意:要注意引入顺序
3.定义模板
定义一个 type="text/html"的 script标签 ,使用 each循环结构 并且...
这样,slice 就包含了
数组中的前三个元素 {1, 2, 3}。需要注意的是,切片表达式中的 low 和 high 可以省略,如果省略 low,则默认从
数组或切片的第一个元素开始;如果省略 high,则默认取到最后一个元素。
```go
slice1 := arr[:3] // 等价于 arr[0:3]
slice2 := arr[2:] // 从第三个元素开始取到最后一个元素
slice3 := arr[:] // 包含整个
数组的所有元素
除了
使用切片表达式外,还可以
使用数组和切片的内置方法来实现类似的功能。例如,可以
使用数组的切片方法来获取
数组中的一段连续元素:
```go
arr := [5]int{1, 2, 3, 4, 5}
slice := arr[0:3]
也可以
使用切片的切片方法来获取切片中的一段连续元素:
```go
slice1 := []int{1, 2, 3, 4, 5}
slice2 := slice1[0:3]