Golang 模板和有效字段测试
Golang template and testing for Valid fields
在 Go 的 database/sql 包中,有一堆 Null[Type] 结构可以帮助将数据库值(及其可能的空值)映射到代码中。我试图弄清楚如何测试结构 field 是否为空,或者换句话说,当它的 Valid 属性 为假时。
打印 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 无效,在这种情况下我会收到错误 "error calling eq: invalid type for comparison"。该错误是有道理的,因为 Go 无法将 nil 字段与另一个值(或类似值)进行比较。
我原以为 'easy' 解决方案是先测试 Value 是否为 nil,然后将其与我需要的进行比较,如下所示:
<select name="y">
{{ range .SomeSlice }}
<option value="{{ . }}" {{ if and ($.MyStruct.MyField) (eq $.MyStruct.MyField.Value .)}}selected="selected"{{ end }}>{{ . }}</option>
{{ end }}
</select>
在这种情况下,我得到相同的 "error calling eq: invalid type for comparison"。我想这意味着 .MyField "exists" 即使 .MyField 的值无效。所以,然后我尝试了六个其他版本,大多数都有相同的错误,例如:
<select name="y">
{{ range .SomeSlice }}
<option value="{{ . }}" {{ if and ($.MyStruct.MyField.Valid) (eq $.MyStruct.MyField.Value .)}}selected="selected"{{ end }}>{{ . }}</option>
{{ end }}
</select>
在这一点上,我意识到我根本不明白如何测试有效字段的存在。如果您能提供任何帮助,我将不胜感激。
谢谢。
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 .)}}
即使如果 $.MyStruct.MyField
为 nil
,条件将被评估为 false
,但 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()
方法在被调用时是否会 return 你一个非 nil
值。它可能看起来像这样:
{{if $.MyStruct.MyField.Valid}}
{{if eq $.MyStruct.MyField.Value .}}selected="selected"{{end}}
{{end}}
在 Go 的 database/sql 包中,有一堆 Null[Type] 结构可以帮助将数据库值(及其可能的空值)映射到代码中。我试图弄清楚如何测试结构 field 是否为空,或者换句话说,当它的 Valid 属性 为假时。
打印 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 无效,在这种情况下我会收到错误 "error calling eq: invalid type for comparison"。该错误是有道理的,因为 Go 无法将 nil 字段与另一个值(或类似值)进行比较。
我原以为 'easy' 解决方案是先测试 Value 是否为 nil,然后将其与我需要的进行比较,如下所示:
<select name="y">
{{ range .SomeSlice }}
<option value="{{ . }}" {{ if and ($.MyStruct.MyField) (eq $.MyStruct.MyField.Value .)}}selected="selected"{{ end }}>{{ . }}</option>
{{ end }}
</select>
在这种情况下,我得到相同的 "error calling eq: invalid type for comparison"。我想这意味着 .MyField "exists" 即使 .MyField 的值无效。所以,然后我尝试了六个其他版本,大多数都有相同的错误,例如:
<select name="y">
{{ range .SomeSlice }}
<option value="{{ . }}" {{ if and ($.MyStruct.MyField.Valid) (eq $.MyStruct.MyField.Value .)}}selected="selected"{{ end }}>{{ . }}</option>
{{ end }}
</select>
在这一点上,我意识到我根本不明白如何测试有效字段的存在。如果您能提供任何帮助,我将不胜感激。
谢谢。
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 .)}}
即使如果 $.MyStruct.MyField
为 nil
,条件将被评估为 false
,但 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()
方法在被调用时是否会 return 你一个非 nil
值。它可能看起来像这样:
{{if $.MyStruct.MyField.Valid}}
{{if eq $.MyStruct.MyField.Value .}}selected="selected"{{end}}
{{end}}