Golang模板和测试有效字段

问题描述 投票:4回答:1

在Go的数据库/ sql包中,有一堆Null [Type]结构有助于将数据库值(及其可能的空值)映射到代码中。我试图弄清楚如何测试struct字段是否为null,或者换句话说,当其Valid属性为false时。

打印SQL字段的推荐方法是使用.Value属性,如下所示:

<div>{{ .MyStruct.MyField.Value }}</div>

这非常有效。

但是假设我有一些稍微复杂的东西,我需要针对其他东西测试值,例如:

<select name="y">
   {{ range .SomeSlice }}
       <option value="{{ . }}" {{ if eq $.MyStruct.MyField.Value .}}selected="selected"{{ end }}>{{ . }}</option>
   {{ end }}
</select>

碰巧,这也很好,除非.MyField不是有效的,在这种情况下我得到错误,“错误调用eq:无效类型进行比较”。这个错误是有道理的,因为Go无法将nil字段与另一个值(或类似的东西)进行比较。

我原以为“简单”的解决方案是首先测试Value是否为nil,然后将其与我需要的进行比较,如下所示:

<select name="y">
   {{ range .SomeSlice }}
       <option value="{{ . }}" {{ if and ($.MyStruct.MyField) (eq $.MyStruct.MyField.Value .)}}selected="selected"{{ end }}>{{ . }}</option>
   {{ end }}
</select>

在这种情况下,我得到相同的“错误调用eq:无效类型进行比较”。我猜这意味着.MyField“存在”,即使.MyField的值不是有效的。那么,我尝试了六个其他版本,大多数都有相同的错误,例如:

<select name="y">
   {{ range .SomeSlice }}
       <option value="{{ . }}" {{ if and ($.MyStruct.MyField.Valid) (eq $.MyStruct.MyField.Value .)}}selected="selected"{{ end }}>{{ . }}</option>
   {{ end }}
</select>

在这一点上,我意识到我真的不明白如何测试是否存在有效字段。我很感激您的帮助。

谢谢。

templates if-statement go go-templates
1个回答
5
投票

Go模板中的and函数不是短路评估的(与Go中的&&运算符不同),它的所有参数都会被评估。引用text/template包文档:

and
    Returns the boolean AND of its arguments by returning the
    first empty argument or the last argument, that is,
    "and x y" behaves as "if x then y else x". All the
    arguments are evaluated.

这意味着你的{{if}}行动:

{{ if and ($.MyStruct.MyField) (eq $.MyStruct.MyField.Value .)}}

即使条件将被评估为false,如果$.MyStruct.MyFieldnil,但eq $.MyStruct.MyField.Value .也将被评估并导致你得到的错误。

相反,你可以嵌入多个{{if}}动作,如下所示:

{{if $.MyStruct.MyField}}
    {{if eq $.MyStruct.MyField.Value .}}selected="selected"{{end}}
{{end}}

您也可以使用{{with}}动作,但也会设置点,所以您必须小心:

<select name="y">
   {{range $idx, $e := .SomeSlice}}
       <option value="{{.}}" {{with $.MyStruct.MyField}}
               {{if eq .Value $e}}selected="selected"{{end}}
           {{end}}>{{.}}</option>
   {{end}}
</select>

注意:

你在谈论你的问题中的nil值,但sql.NullXX类型是结构,不能是nil。在这种情况下,您必须检查其Valid字段,以告知其Value()方法在调用时是否会返回非nil值。它可能看起来像这样:

{{if $.MyStruct.MyField.Valid}}
    {{if eq $.MyStruct.MyField.Value .}}selected="selected"{{end}}
{{end}}
© www.soinside.com 2019 - 2024. All rights reserved.