Вопрос
Как мне сделать что-то вроде этого:
{{ $use_ssl := (ne $.Env.CERT_NAME "") }}
где $.Env.CERT_NAME
может быть нулем / неопределенным. Если он равен нулю, выдается следующая ошибка:
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, который, очевидно, if/else
.
{{ if $.Env.CERT_NAME }}
{{ $use_ssl := (ne $.Env.CERT_NAME "") }}
{{ else }}
{{ $use_ssl := false }}
{{ end }}
Но тогда, конечно, у меня возникают проблемы с областью видимости, потому что if
необъяснимо (или, по крайней мере, досадно) создает новую область видимости переменной (в отличие от шаблонов Ruby / ERB, к которым я больше привык), поэтому, очевидно, я даже не могу этого сделать:
{{ if $.Env.CERT_NAME }}
{{ $use_ssl := true }}
{{ else }}
{{ $use_ssl := false }}
{{ end }}
# $use_ssl: {{ $use_ssl }}
без получения этой ошибки сейчас:
undefined variable "$use_ssl"
«Без пота», - подумал я. Я просто объявлю переменную во внешней области видимости, чтобы она имела правильную область видимости, а внутренняя область все еще могла изменять эту переменную (ту, которая имеет внешнюю область видимости). (Кстати, именно так это работает в Ruby.)
Нет, по-видимому, все, что нужно сделать, это создать 2 разные переменные с одинаковым именем, но с разными областями действия (как это запутать!):
{{ $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
Очевидно, операторы if
нельзя использовать в качестве выражений в Go, как в Ruby?
Я также получаю синтаксические ошибки, если попробую различные альтернативы тернарному оператору, предложенные в Что такое идиоматический эквивалент троичного оператора C в Go?, например:
c := map[bool]int{true: 1, false: 0} [5 > 4]
И конечно, вы можете читать переменные из внешних областей во внутренних областях с помощью $.something
, но как вы установить $.something
во внутренней области?
Если не так, то как ???
Так что я упустил? Возможно ли это вообще в шаблоне Go?
Шаблоны Go (я новичок в них) кажутся очень ограничивающими. Практически все, что вы можете делать в Go, невозможно в шаблоне. Но, надеюсь, есть обходной путь ...
У http://play.golang.org/p/SufZdsx-1v есть умный обходной путь включая создание нового объекта с {{$hasFemale := cell false}}
, а затем установку значения с $hasFemale.Set true
, но как я могу сделать что-то подобное, не имея доступа к коду, который оценивает шаблон (где они вызывают template.FuncMap
)?
Другие, которые пытались и потерпели неудачу
https://groups.google.com/forum/#!topic/golang-nuts/MUzNZ9dbHrg
Это самая большая (и единственная) проблема с Go. Я просто не понимаю, почему до сих пор не реализован этот функционал.
Когда пакет шаблона используется в общем контексте (например, при выполнении произвольного файла шаблона с произвольным файлом json), у вас может не быть возможности выполнить предварительные вычисления.
https://github.com/golang/go/issues/10608
Вероятно, это так, как задумано, но было бы очень хорошо, если бы существовал способ получить измененный $ v за пределами условного оператора.
Это шаблонный вопрос №1, который мы решаем в Hugo (https://github.com/spf13/hugo). Мы добавили хак [
$.Scratch.Set "v1" 123
], чтобы пока обойти это ...
{{ if ... }} assignment here {{ end }}
не удалось! - person consideRatio   schedule 07.04.2018