go text/template: 添加对可选链的支持

rnmwe5a2  于 3个月前  发布在  Go
关注(0)|答案(8)|浏览(52)

如果包 text/template(例如由 Helm 使用)能够支持可选链式调用,那将会很美好。类似于最新标准的 ECMAScript 2020 中的 JavaScript。参见 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining
它基本上看起来像这样:

spec:
  type: {{ .Values.service?.type | default "ClusterIP" }}

如果服务未定义,它将短路到 undefined/false 并默认为 "ClusterIP"。
这可以在其他情况下使用,例如:

spec:
  {{- if .Values.global?.internalIPFamily }}
  ipFamily: {{ .Values.global.internalIPFamily }}
  {{- end }}

它解决了一些在 e.g. Helm 中使用 text/template 进行模板化的问题:

  1. 当链中的父值不存在时,default 无法工作,导致错误,参见 nil pointer evaluating interface when upper level doesn't exist prevents usage of default function helm/helm#8026
  2. 它将能够摆脱我认为不是很好的做法,即对于 e.g. Helm 的嵌套或扁平值(我认为这也适用于其他 text/template 的使用),参见 https://helm.sh/docs/chart_best_practices/values/#flat-or-nested-values。可选链式调用仍然会使代码更具可读性(一行代码),而不必关心值的深度。在我看来,它还使阅读具有嵌套结构的 YAML 文件更容易,清晰地分隔层次,而不是使用驼峰命名法。
    由于我对 Go 和包 text/template 知之甚少,如有更多关于如何在 text/template 中实现此功能的精确信息,请随时补充。
9w11ddsr

9w11ddsr1#

这看起来更像是一个建议。我添加了文本/模板所有者以便开始讨论。
/cc @robpike@mvdan

6ljaweal

6ljaweal2#

请@cagedmantis@robphoenix@mvdan更新此任务的进展?如果我们能使用这种属性解析器样式,那将是非常有帮助的。

4szc88ey

4szc88ey3#

@bilak @cagedmantis @robphoenix @mvdan 你对此有什么看法?

i2loujxw

i2loujxw4#

有数十个开放的文本/模板问题。请不要每隔几周就发送提案;我们时间有限。
就我个人而言,我认为在考虑新提案之前,我们应该先实施已经接受的提案(#20531#31103)。对于这些提案的任何帮助都是受欢迎的。

pbgvytdp

pbgvytdp5#

这是5个月前写的,我认为给已阅读的简短评论是一种常见的礼貌。但每个人都有自己的看法。

6uxekuva

6uxekuva6#

要在这个项目上取得进展,需要将其变成一个 proposal ,并对建议的更改和新语义给出精确的定义。
例如,如果我将

var s struct {
    p *struct {
        f int
    }
}

传递给一个模板并写入 s.p.f ,然后假设 s.p 不是 nil ,我会得到一个整数。对于 s.p.?f ,如果 p 是 nil ,我应该得到 0 吗?如果我得到 nil ,那可能会导致不同的错误。
关于这个问题的初始评论是“请随意添加更多关于如何将此转换为文本/模板中需要完成的操作的详细信息”,但这对我们来说很难做到。有很多很多人提出了更改的建议,但实施这些更改的人却很少。只有当对更改感兴趣的人能够准确描述它应该如何工作时,这种情况才能扩大规模。
谢谢。

brccelvz

brccelvz7#

@ianlancetaylor 我没有Go语言的知识来给出具体细节,但是关于语义方面,可以查看 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining ,它可以作为其工作方式的规范。
然而关于 s.p?.f ,它应该返回 nil (在Go中未定义的since不存在?)。
任何更熟悉Go的人;请随意编写一个合适的提案。我可以将其链接到原始问题中。

ahy6op9u

ahy6op9u8#

There is no value in nil pointer panics and maybe not much code that depends on it to work properly. Because it just breaks things and doesn't fix anything, the nicest solution would be to make optional chaining the default.
Now I know we can't have nice things because of the remote chance that some code depends on the panics, backward compatibility and all, so the next best thing would be to make it a configuration option on template level.

相关问题