zoukankan      html  css  js  c++  java
  • go 模板详说

    模板是我们常用的手段用于动态生成页面,或者用于代码生成器的编写等。比如把数据库的表映射成go语言的struct,这些体力活,写个代码生成器是最合适不过的了.
    示例例把表转成 struct :

    当然这篇帖子不是写关于代码生成器的,是详细说一下goTemplate,对Template的操作熟悉了后,就可以利用他实现你想要的一些功能。

    渲染对象

    {{.}}来渲染对象本身,对象内部的字段可以{{.field}}
    比如下面,我是用一个 map来存储的数据,访问key: name,并使用{{.}}来把 map打印出来
    eg:

    	tmpl, err := template.New("test").Parse(`hello {{.name}}!
    	obj: {{.}}`)
    	if err != nil {
    		panic(err)
    	}
    	err = tmpl.Execute(os.Stdout, map[string]interface{}{
    		"name": "world", "age": 18})
    	if err != nil {
    		panic(err)
    	}
    

    输出

    hello world!
    obj: map[age:18 name:world]
    

    结构体内的字段也是用{{.field}}

    	tmpl, err := template.New("test").Parse(`hello {{.Name}}!
    	obj: {{.}}`)
    	if err != nil {
    		panic(err)
    	}
    	err = tmpl.Execute(os.Stdout, struct {
    		Name string
    		Age  int
    	}{Name: "li", Age: 18})
    	if err != nil {
    		panic(err)
    	}
    

    空格

    {{}}内添加 -可以去掉空格

    • {{- }} 去掉左边所有的空格
    • {{ -}} 去掉右边所有的空格
    • {{- -}} 去掉两边所有的空格
      eg:
    	tmpl, err := template.New("test").Parse(`hello:    {{- .Name}}
    	age: {{.Age -}}   !!!
    	obj:     
    	{{- . -}}   end.`)
    	if err != nil {
    		panic(err)
    	}
    	err = tmpl.Execute(os.Stdout, struct {
    		Name string
    		Age  int
    	}{Name: "li", Age: 18})
    	if err != nil {
    		panic(err)
    	}
    
    • hello: 后面的空格到{{- .Name}} 之间的空格会被去掉.
    • {{.Age -}}!!!之间的空格会被去掉
    • obj:{{- . -}}end.之间的空格都会被去掉。
    hello:li
    age: 18!!!
    obj:{li 18}end.
    

    自定义变量

    除了可以直接使用go的对象,也可以直接在模板中定义变量{{ $var := }},变量定义后,可以在模板内其他任意地方使用:

    	tmpl, err := template.New("test").Parse(`{{$a := "li"}} hello {{$a}}`)
    	if err != nil {
    		panic(err)
    	}
    	err = tmpl.Execute(os.Stdout, nil)
    	if err != nil {
    		panic(err)
    	}
    

    输出

    hello li
    

    方法

    方法可以分为全局方法和结构体方法还有内置方法,内置方法也是全局方法的一种

    全局方法

    template.FuncMap 是一个map里面的value必需是方法,传入的值的参数没有限制

    type FuncMap map[string]interface{}
    

    比如:定义一个ReplaceAll方法,替换所有的指定字符串
    例子中把所有的zhang替换成li

    	tmpl, err := template.New("test").Funcs(template.FuncMap{
    		"ReplaceAll": func(src string, old, new string) string {
    			return strings.ReplaceAll(src, old, new)
    		},
    	}).Parse(`func replace:  {{ReplaceAll .Name "zhang" "li"}}`)
    	if err != nil {
    		panic(err)
    	}
    	err = tmpl.Execute(os.Stdout, struct {
    		Name string
    		Age  int
    	}{Name: "zhang_san zhang_si", Age: 18})
    	if err != nil {
    		panic(err)
    	}
    

    输出

    func replace:  li_san li_si
    

    内置方法

    模板有一些内置方法比如 call printf 等,和全局方法一样,直接调用就行

    	tmpl, err := template.New("test").Parse(`{{printf "name: %s age: %d" .Name .Age}}`)
    	if err != nil {
    		panic(err)
    	}
    	err = tmpl.Execute(os.Stdout, struct {
    		Name string
    		Age  int
    	}{Name: "li", Age: 18})
    	if err != nil {
    		panic(err)
    	}
    

    输出

    name: li age: 18
    

    行为

    常用的行为有if range template

    if

    判断 {{if }} {{end}},可以用于字符串 bool 或者数值类型
    字符串有数据 或者bool值为true 或者数值类型大于0 时为真

    	tmpl, err := template.New("test").Parse(`
    	name: {{.Name}} 
    	{{- if .Name}}
          string .Name true 
    	{{else}} 
          string .Name false 
    	{{end -}}
    	desc: {{.Desc}} 
    	{{- if .Desc}}
          string .Desc true 
    	{{else}} 
          string .Desc false 
    	{{end -}}
    	age: {{.Age}} 
    	{{- if .Age}}
          number .Age true 
    	{{else}} 
    	  number .Age true false
    	{{end -}}
    	isAdmin: {{.IsAdmin}} 
    	{{- if .Age}}
          bool .IsAdmin true 
    	{{else}} 
    	  bool .IsAdmin true false
    	{{end}}
    	`)
    	if err != nil {
    		panic(err)
    	}
    	err = tmpl.Execute(os.Stdout, struct {
    		Name    string
    		Desc    string
    		Age     int
    		IsAdmin bool
    	}{Name: "", Desc: "xyz", Age: 18, IsAdmin: true})
    	if err != nil {
    		panic(err)
    	}
    

    输出:

    	name:  
          string .Name false 
    	desc: xyz
          string .Desc true 
    	age: 18
          number .Age true 
    	isAdmin: true
          bool .IsAdmin true
    

    range

    range 用于遍例数组,和gorange一样,可以直接得到每个变量,或者得到 indexvalue

    	tmpl, err := template.New("test").Parse(`
    	{{range .val}} {{.}} {{end}}
    	{{range $idx, $value := .val}} id: {{$idx}}: {{$value}} {{end}}`)
    	if err != nil {
    		panic(err)
    	}
    	err = tmpl.Execute(os.Stdout, map[string]interface{}{
    		"val": []string{"a", "b", "c", "d"}})
    	if err != nil {
    		panic(err)
    	}
    

    输出

    a  b  c  d 
    id: 0: a  id: 1: b  id: 2: c  id: 3: d
    

    内嵌template

    除了可以在自定义对象还可以自定义内嵌的模板{{define "name"}},也可以传参数

    	tmpl, err := template.New("test").Parse(`
    	{{define "content"}} hello {{.}} {{end}}
    	content: {{template "content" "zhang san"}}`)
    	if err != nil {
    		panic(err)
    	}
    	err = tmpl.Execute(os.Stdout, nil)
    	if err != nil {
    		panic(err)
    	}
    

    在调用时{{template "content" "zhang san"}} 传递了参数 zhang san
    输出:

    content:  hello zhang san
    

    注释

    模板的注释: {{/* comment */}}

    	tmpl, err := template.New("test").Parse(`
    	{{/* 注释 */}}
    	{{define "content"}} hello {{.}} {{end}}
    	content: {{template "content" "zhang san"}}`)
    	if err != nil {
    		panic(err)
    	}
    	err = tmpl.Execute(os.Stdout, nil)
    	if err != nil {
    		panic(err)
    	}
    
  • 相关阅读:
    固定执行计划-SQL PROFILE手工绑定
    其他典型的执行计划
    oracle-常见的执行计划(一)
    DBMS_XPLAN详细说明
    sql-查看执行计划的方法
    CBO基础概念
    webpack生产环境保留某些console.log
    提升webpack构建速度(二)
    提升webpack构建速度(一)
    【译文】更有效的调试webpack在构建时出现的错误
  • 原文地址:https://www.cnblogs.com/li-peng/p/12835425.html
Copyright © 2011-2022 走看看