当前位置: 首页 > 知识库问答 >
问题:

如何基于表达式在Go模板中有条件地设置变量,如果不使用if语句包装,可能会导致错误

拓拔嘉运
2023-03-14

我怎么做这样的事情:

{{ $use_ssl := (ne $.Env.CERT_NAME "") }}

其中<code>$.Env。CERT_NAME可能为nil/undefined。如果为零,则给出以下错误:

at <ne $.Env.CERT_NAME "">: error calling ne: invalid type for comparison

注意:我无法控制传递给Go模板的对象,因此必须完全在模板本身中解决这个问题。

我尝试先检查它是否为非空:

{{ $use_ssl := ( ($.Env.CERT_NAME) && (ne $.Env.CERT_NAME "") ) }}

但它给出了这个错误:

unexpected "&" in operand

所以我切换到这个,这是语法上允许的:

{{ $use_ssl := (and ($.Env.CERT_NAME) (ne $.Env.CERT_NAME "") ) }}

但随后我失去了我会得到的短路评估

at <ne $.Env.CERT_NAME ...>: error calling ne: invalid type for comparison

好吧,我想,如果我不能在一行代码中实现它,而且Go没有三元运算符,那也没关系,我就用惯用的Go方式,显然是< code>if/else

{{ if $.Env.CERT_NAME }}
  {{ $use_ssl := (ne $.Env.CERT_NAME "") }}
{{ else }}
  {{ $use_ssl := false }}
{{ end }}

但是我当然会遇到范围问题,因为< code>if莫名其妙地(或者至少令人讨厌地)创建了一个新的变量范围(不像我更习惯的Ruby/ERB模板),所以显然我甚至不能这样做:

{{ if $.Env.CERT_NAME }}
  {{ $use_ssl := true }}
{{ else }}
  {{ $use_ssl := false }}
{{ end }}
# $use_ssl: {{ $use_ssl }}

而不会立即得到此错误:

undefined variable "$use_ssl"

“别出汗”,我想。我将只在外部范围内声明变量,这样它将具有正确的范围,并且内部范围仍然能够更改该变量(具有外部范围的变量)。(顺便说一下,这就是它在Ruby中的工作原理。)

不,显然,所做的只是创建两个不同的变量,名称相同但作用域不同(这怎么会让人困惑!):

{{ $use_ssl := false }}
{{ if $.Env.CERT_NAME }}
  {{ $use_ssl := true }}
  # $use_ssl: {{ $use_ssl }}
{{ else }}
  {{ $use_ssl := false }}
{{ end }}
# $use_ssl: {{ $use_ssl }}

  # $use_ssl: true
# $use_ssl: false

我还尝试过像这样内联if语句:

{{ $use_ssl := if $.Env.CERT_NAME { true } }}

但这给出了这个错误:

unexpected <if> in command

显然,如果语句不能像在 Ruby 中那样在 Go 中用作表达式?

如果我尝试三元运算符的各种替代方法,我也会遇到语法错误?,例如:

c := map[bool]int{true: 1, false: 0} [5 > 4]

当然,您可以使用<code>$从内部作用域中的外部作用域读取变量。有些,但如何设置$。内部作用域中有什么

那么我错过了什么?这在Go模板中可能吗?

围棋模板(我是新手)似乎非常有限。你在围棋中能做的几乎所有事情都不可能在模板中完成。但希望有一个解决办法。。。

http://play.golang.org/p/SufZdsx-1v有一个巧妙的解决方法,包括使用{{$has女性:=cell false}}创建一个新对象,然后使用$has女性设置一个值。设置为真,但是我怎么能在没有访问评估模板的代码的情况下做这样的事情(在那里他们调用模板。函数地图)?

https://groups.google.com/forum/#!topic/golang-nuts/MUzNZ9dbHrg

这是我对围棋最大的(也是唯一的)问题。我只是不明白为什么这个功能还没有实现。

当模板包在通用上下文中使用时(例如。使用任意 json 文件执行任意模板文件),您可能没有进行预计算的奢侈。

https://github.com/golang/go/issues/10608

这可能是设计好的,但如果有一种方法可以在条件之外获得更改$v,那就太好了。

这是我们在雨果(https://github.com/spf13/hugo)上得到的#1模板问题。我们添加了一个黑客 [$.Scratch.Set “v1” 123] 暂时解决它...

共有3个答案

梁建德
2023-03-14

我想我可能已经为我的特定问题找到了一个变通方法,尽管我很想听到更普遍地解决问题的其他答案。

在 https://github.com/jwilder/nginx-proxy/blob/1e0b930/nginx.tmpl#L91 遇到了这一行:

{{ $default_host := or ($.Env.DEFAULT_HOST) "" }}

这给了我另一个尝试的想法。我想解决方案是使用 or 的组合并设置额外的临时变量......

{{ $cert_name := or $.Env.CERT_NAME "" }}
{{ $use_ssl := ne $cert_name "" }}
郁宾鸿
2023-03-14

如果您使用赋值运算符而不是定义运算符,则第四次尝试将起作用:

{{ $use_ssl := false }}
{{ if $.Env.CERT_NAME }}
  {{ $use_ssl = true }} # notice the missing colon!
{{ else }}
  {{ $use_ssl = false }}
{{ end }}
司马作人
2023-03-14

如果更新范围而不是声明变量,则可以使用setmerge在If子句之外访问它。

{{- if eq .podKind "core" -}}
{{- $dummy := set . "matchNodePurpose" .Values.scheduling.corePods.nodeAffinity.matchNodePurpose }}
{{- else if eq .podKind "user" -}}
{{- $dummy := set . "matchNodePurpose" .Values.scheduling.userPods.nodeAffinity.matchNodePurpose }}
{{- end -}}

# Will now output what you decided within an if/else if clause
{{- .matchNodePurpose }}

我在Helm模板的上下文中遇到了同样的问题,Helm模板是预装了一些附加功能的go模板,例如Sprig。

2018年3月28日,在本次公关中,Sprig增加了一名三岁操作员,Helm将及时让他们解决您和我的问题。

三元

true|三元"b""c"将返回"b"

< code>false |三元" b" "c"将返回< code>"c"

 类似资料:
  • 我的 views.py 交出了一个名为“preSelect”的变量,其中包含一个整数值。 在模板中,我想在 If 语句中使用该 Integer 来检查当前 for 循环计数器是否小于或大于我的值。 但是,这会返回以下错误: 环境: 申请方式: POST申请网址:http://127.0.0.1:8000/ Django版本:1.10.2 Python版本:2.7.11安装的应用:['django.

  • 我有一个包含单选按钮选项的表单,我想用它来指示一组变量的值。 单选按钮如下: 我能够回声单选按钮的值 所以我确信变量正在被继承。由于我将 $_POST 值传递给元素,以便用户看到选择了哪个值,因此我想我会使用元素 ID 来获取我的 if-else 语句的值。 下面是我的if-else语句的样子: 然后,我将此URL传递给一个按钮,该按钮有一个空的href,其中包含以下行: 但是,每当我单击链接时,

  • 问题内容: 我想删除以AAA开头的Jenkins作业列表(例如) 当我用显式字符串做它很好用 但是,当我尝试从Jenkins Build属性获取正则表达式时,我失败了,并且if没有被调用… 运行它时,我会得到所有作业的列表:在工作区中构建/ var / lib / jenkins / jobs / Bulk_Delete_Job / workspace 但是什么也不会被删除/不会打印“ TEST”

  • 如何重构我的代码,以便我的 for 表达式中没有 if 语句? 我得到一个执行异常: 我正在下面定义一个if选项,这导致了问题: 我应该开始使用什么模式来避免此错误?

  • 问题内容: 我想知道如何将变量传递给我的所有模板,而无需在views.py文件中的每个方法上重复相同的代码? 在下面的示例中,我想使类别(类别对象的数组)可用于Web应用程序中的所有模板。 一种查看方法 另一种查看方法 问题答案: 你需要的是上下文处理器,创建一个上下文处理器非常容易。假设你有一个名为的应用custom_app,请执行以下步骤: 加入到 在(你已经做了了,对不对?); 创建一个文件