Шаблон Golang и тестирование на допустимые поля - PullRequest
0 голосов
/ 04 июля 2018

В пакете базы данных / sql Go есть несколько структур Null [Type], которые помогают отображать значения базы данных (и их возможные значения NULL) в код. Я пытаюсь выяснить, как проверить, имеет ли значение struct field значение 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: invalid type для сравнения". Ошибка имеет смысл, потому что Go не может сравнивать нулевое поле с другим значением (или чем-то подобным).

Я бы подумал, что «легким» решением было бы сначала проверить, является ли Значение ноль, а затем сравнить его с тем, что мне нужно, например:

<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>

На данный момент, я понимаю, что я действительно не понимаю, как проверить наличие действительного поля вообще. Буду признателен за любую помощь.

Спасибо.

1 Ответ

0 голосов
/ 04 июля 2018

Функция and в шаблонах Go не оценивается при коротком замыкании (в отличие от оператора && в 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.MyField равно nil, но 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() возвращать вам не-1038 * значение при вызове. Это может выглядеть так:

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