我有一个通过template渲染的 struct .例如:

type Foo struct {
  Created time.Time
  ...
}

我将此值传递给一个模板,并希望呈现该值,请参见:

  Created at 2022-11-22 9:50 (0d1h12m34s ago)

显示时间戳(并对其进行格式化)非常简单,但我找不到一种计算时间间隔的方法.

Created at {{.Created}} ({{???}} ago)

在GO中,这将由time.Since(foo.Created)完成,它返回Duration,然后我可以用各种方法将持续时间转换为字符串.

但在模板本身中进行计算似乎是不可能的:

function "time" not defined

还是真的是这样? 我找不到任何明确告诉我模板中永远不允许使用time(或其他任意函数)的信息.所以我不知道我是不是说错了.

(我知道我可以从Foo添加该字段来创建一个新的FooTemplateValue,这样模板就可以按原样呈现持续时间.我只是尽量避免它,并按原样使用实际对象).

推荐答案

您可以使用template.FuncMap注册一个自定义模板函数,然后可以像调用内置函数一样在模板内调用该函数.

template.New("").Funcs(template.FuncMap{
    "dur_until_now": func(t time.Time) time.Duration {
        return time.Now().Sub(t)
    },
}).Parse(`{{ dur_until_now .Created }}`)

https://go.dev/play/p/wM2f1oDFtDr


或者,您可以声明一个自定义时间类型,并让该类型实现一个生成所需值的方法,然后您可以在模板内直接在该字段上调用该方法.

type MyTime struct{ time.Time }

func (t MyTime) DurUntilNow() time.Duration {
    return time.Now().Sub(t.Time)
}

// ...
.Parse(`{{ .Created.DurUntilNow }}`)

https://go.dev/play/p/3faW4nTzK3-

Go相关问答推荐

区分Terminal和Hook Zerolog Go中的错误级别日志(log)输出

Makefile:现有文件上没有这样的文件或目录,不加载环境变量

获取作为类型参数传递给方法接收方中的类型参数的切片的基础类型

golang有int32溢出吗?

将这两个函数合二为一的惯用方法

这是go语言gin提供的关于TypeEngine和RouterGroup的问题

Go 中将 int 切片转换为自定义 int 切片指针类型的函数

如何将 goose 迁移与 pgx 一起使用?

如何在正则表达式中使整个单词可选?

Fizz对Gin的OpenAPI生成器正在重命名类型

使用goqu无法获取响应

如何为ANTLR4目标Go调试监听器

GitHub 中 REST API 的 aws 凭证问题

如何在 Golang 中打印 2 列表?

Golang Oauth2 服务帐户返回空刷新令牌字符串

如何在Go中替换符号并使下一个字母大写

如何优雅地映射到 Go 中返回可变长度数组的方法?

HTTP 重定向不呈现新页面

Go Flag 用法 描述 包含 Word 值

更改单个像素的 colored颜色 - Golang 图像