Golang模板并测试有效字段 [英] Golang template and testing for Valid fields
问题描述
在Go的数据库/sql程序包中,有一堆Null [Type]结构可帮助将数据库值(及其可能的null)映射到代码中.我试图弄清楚如何测试结构 field 是否为空,或者换句话说,当其Valid属性为false时.
In Go's database/sql package, there are a bunch of Null[Type] structs that help map database values (and their possible nulls) into code. I'm trying to figure out how to test whether a struct field is null, or in other words, when its Valid property is false.
建议的打印SQL字段的方法是使用.Value属性,如下所示:
The recommended way to print a SQL field is to use the .Value property, like this:
<div>{{ .MyStruct.MyField.Value }}</div>
这很好.
但是假设我有一些更复杂的东西,例如,我需要在其他地方测试该值,例如:
But suppose I have something slightly more complicated, where I need to test the value against something else, for example:
<select name="y">
{{ range .SomeSlice }}
<option value="{{ . }}" {{ if eq $.MyStruct.MyField.Value .}}selected="selected"{{ end }}>{{ . }}</option>
{{ end }}
</select>
碰巧的是,这也很好用,除非.MyField无效,在这种情况下,我会收到错误消息:错误调用eq:用于比较的无效类型".该错误是有道理的,因为Go无法将nil Field与另一个值(或类似值)进行比较.
As it happens, this works great, too, unless .MyField is not Valid, in which case I get the error, "error calling eq: invalid type for comparison". The error makes sense, because Go can't compare a nil Field against another value (or something like that).
我本以为简单"的解决方案是先测试Value是否为nil,然后将其与所需的值进行比较,如下所示:
I would have thought the 'easy' solution would be to test first whether the Value is nil, and then compare it against what I need, like this:
<select name="y">
{{ range .SomeSlice }}
<option value="{{ . }}" {{ if and ($.MyStruct.MyField) (eq $.MyStruct.MyField.Value .)}}selected="selected"{{ end }}>{{ . }}</option>
{{ end }}
</select>
在这种情况下,我得到相同的调用eq:进行比较的无效类型时出错".我猜这意味着.MyField存在",即使.MyField的值无效.所以,然后我尝试了六个其他版本,大多数都存在相同的错误,例如:
In this case, I get the same "error calling eq: invalid type for comparison". I guess that means .MyField "exists" even though the value of .MyField is not Valid. So, then I tried a half dozen other versions, mostly with the same error, for example:
<select name="y">
{{ range .SomeSlice }}
<option value="{{ . }}" {{ if and ($.MyStruct.MyField.Valid) (eq $.MyStruct.MyField.Value .)}}selected="selected"{{ end }}>{{ . }}</option>
{{ end }}
</select>
至此,我意识到我真的根本不了解如何测试有效字段的存在.非常感谢您的帮助.
At this point, I'm realizing I really don't understand how to test for the existence of a valid field at all. I'd appreciate any help you might have.
谢谢.
推荐答案
Go模板中的and
函数不是短路求值的(不同于Go中的&&
运算符),它的所有参数总是被求值的.引用 text/template
包doc:
The and
function in Go templates is not short-circuit evaluated (unlike the &&
operator in Go), all its arguments are evaluated always. Quoting from text/template
package doc:
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 .
并导致错误.
Even though the condition would be evaluated to false
if $.MyStruct.MyField
is nil
, but eq $.MyStruct.MyField.Value .
will also be evaluated and result in the error you get.
相反,您可以嵌入多个{{if}}
操作,如下所示:
Instead you may embed multiple {{if}}
actions, like this:
{{if $.MyStruct.MyField}}
{{if eq $.MyStruct.MyField.Value .}}selected="selected"{{end}}
{{end}}
您也可以使用{{with}}
动作,但这也会设置点,因此您必须小心:
You may also use the {{with}}
action, but that also sets the dot, so you have to be careful:
<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
值.看起来可能像这样:
You were talking about nil
values in your question, but the sql.NullXX
types are structs which cannot be nil
. In which case you have to check its Valid
field to tell if its Value()
method will return you a non-nil
value when called. It could look like this:
{{if $.MyStruct.MyField.Valid}}
{{if eq $.MyStruct.MyField.Value .}}selected="selected"{{end}}
{{end}}
这篇关于Golang模板并测试有效字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!