使用text/template包中的template.FuncMap,您可以直接从GO模板文件中访问函数.

假设以下场景:在用户概述页面的处理程序中,调用函数GetAllUsers并将用户对象传递给具有ExecuteTemplate的模板:

func index(w http.ResponseWriter, r *http.Request) {
  users, err := model.GetAllUsers()
  if err != nil {
    render50x()
    return
  }

  data := make(map[string]interface{})
  data["userList"] = users

  render(w, r, data, "layout", "index")
}

这是否等同于将函数传递给模板并在那里执行?

var funcs = template.FuncMap{
  "getAllUsers": model.GetAllUsers,
}

// func render
t := template.New("render").Funcs(funcs)
if err := template.Must(t.ParseFS(ViewsFS, files...)).ExecuteTemplate(w, layout, data); err != nil {
  log.Println("Error executing template:", err.Error())
}

{{ range getAllUsers }}
  {{ .DisplayName }}
{{ end }}

这两种方法有什么不同吗?

推荐答案

如果您可以从模板中调用该函数,则它是相同的.以下是一些区别:

如果你在GO中调用它,你不需要注册函数.有时您无法使用模板解析来注册函数,因此这是唯一的方法(别忘了:您必须在解析模板之前注册函数).

此外,如果你在围棋中调用它,你对它有更多的"控制":你可以从panic 中恢复过来,你可以对结果进行预处理,你可以在其他围棋代码中重新使用它.您还可以 Select 不根据结果执行模板,或者执行模板中可能无法(轻松)表达的其他操作.

函数的结果也可能不是容易呈现的东西.例如,它可能不是string,或者可能没有String() string方法.因此,可能需要一些额外的(GO)逻辑来将结果转换为人类可读的格式,这可能在模板中不可用,或者可能需要注册更多的函数.

还要注意,并不是所有的函数都可以从模板注册和调用.可调用函数最多可以有2个返回类型,秒数可能只有error.在Go中,您可以调用"任何"函数,并且只传递您需要的结果.如果函数有参数,您还必须将这些参数作为数据传递给模板执行(以便在调用函数时可以在模板中传递它们).

Go相关问答推荐

Golang Cososdb-gremlin连接

Golang Viper:如果第一个字段不存在,如何从另一个字段获取值

有没有办法通过Go cmdline或IDE(IntelliJ)找出我的 struct 实现了什么接口?

Golang使用Run()执行的命令没有返回

使用!NOT运算符的Golang文本/模板多个条件

golang testscript .txtar 语法,用于 stderr 或 stdout 中包含的文本

Golang和Gin web框架在router.Run()之后执行代码

如何在 Go msgraph-sdk-go 中转发消息并包括抄送和/或密送收件人?

Go 中的 Azure JWT 验证不起作用

Golang 中的泛型类型转换

go - 仅在函数即将返回错误时清理资源

我如何使用 TOML fixtures 在使用 Go Buffalo 框架的开发环境中为我的数据库 seeder ?

我在 go 中制作的递归函数有什么问题?

使用 os/exec 和在命令行执行之间的结果莫名其妙地不同

在嵌套模板中使用变量,它也被定义为 go 模板中的变量?

使用 GO 在侧 tar 文件中提取 tar 文件的最快方法

来自洪流公告的奇怪同行字段

K8s 算子读取原始数据

如何使路径/不匹配 Golang net/http 中所有其他不匹配的路径

Golang 将类型 [N]byte 转换为 []byte