Перейти альтернатива для Python loop.last

Я пытаюсь перебрать массив с помощью шаблонов Go и хочу добавить дополнительную строку в последний элемент цикла.

В питоне я могу сделать

{% for host in hosts %}
{{ host }}{% if loop.last %} ;{% endif %}
{% endfor %}

Ниже приведен фрагмент эквивалента Go.

{{ range $host := $hosts }}
{{$host}}
{{ end }}

Благодарю.

1 ответ

Решение

Если список не пустой, то фрагмент кода Python выводит точку с запятой после последнего элемента. Вы можете добиться того же результата в Go, заключив диапазон в if, чтобы проверить, есть ли хотя бы один элемент в срезе, и распечатать; вне петли.

{{if $hosts}}{{range $host := $hosts}}
{{$host}}
{{ end }} ;{{end}}

Этот фрагмент работает, потому что вы добавляете в конец последний элемент. Более общее решение требует пользовательской функции шаблона. Вот пример функции:

func last(v interface{}, i int) (bool, error) {
  rv := reflect.ValueOf(v)
  if rv.Kind() != reflect.Slice {
    return false, errors.New("not a slice")
  }
  return rv.Len()-1 == i, nil
}

и вот как использовать его в шаблоне:

{{range $i, $host := $hosts }}
{{$host}}{{if last $hosts $i}} ;{{end}}
{{ end }}

Я опубликовал рабочий пример пользовательской функции на игровой площадке.

Альтернативой является определение функции декремента, например,

    "dec": func(n int) int { return n - 1 },

Затем вы можете использовать dec функция для вычисления последнего элемента, например,

{{$last := dec (len $hosts)}}
{{range $i, $host := $hosts}}
{{$host}}{{if eq $i $last}} ;{{end}}
{{end}}

Конечно, было бы проще, если бы шаблоны Go допускали вычитание, чтобы можно было писать {{$last := (len $hosts) - 1}}. В конце концов, они настаивают на том, чтобы перед или после знака минуса был пробел, так почему бы не разрешить простую арифметику?

Другие вопросы по тегам